如何有效地从 JSON 列中提取字段?

Posted

技术标签:

【中文标题】如何有效地从 JSON 列中提取字段?【英文标题】:how to efficiently extract fields from a JSON column? 【发布时间】:2020-04-18 17:26:09 【问题描述】:

考虑以下示例

data1 = ['type': 'one', 'delta': '1', 'time': '2019', 'type': 'two', 'delta': '1', 'time': '2018']
data2 = ['type': 'one', 'delta': '1', 'time': '2013', 'type': 'two', 'delta': '1', 'time': '2012']


dftest = pd.DataFrame('weirdjson' : [data1, data2])
dftest['normalcol'] = 1

dftest

Out[79]: 
                                                                                        weirdjson  normalcol  time_type_one  time_type_two
0  ['type': 'one', 'delta': '1', 'time': '2019', 'type': 'two', 'delta': '1', 'time': '2018']          1           2019           2018
1  ['type': 'one', 'delta': '1', 'time': '2013', 'type': 'two', 'delta': '1', 'time': '2012']          1           2013           2012

基本上,我想创建两列time_type_onetime_type_two,每列都包含它们对应的time 值(第一行:2019 对应type one2018 对应type two) .

如何在 Pandas 中做到这一点?我有很多行,所以我正在寻找非常有效的东西。 谢谢!

【问题讨论】:

我没有投反对票,但我认为人们投反对票,因为没有显示任何尝试。另外,如果我们复制此数据框,它将被复制为字符串列,而不是字典列表。因此,最好将您的示例数据框作为可复制代码包含在pd.DataFrame(..) 好点。让我改变一下 既然你在它。最好以数据框的形式包含预期输出,这样人们就可以直观地看到您尝试做什么。 我觉得你可以看看这个:***.com/questions/39899005/… 问题已更新! 【参考方案1】:

试试这个:

import json
import pandas as pd

data = ['normalcol':1, 'weirdjsoncol':'["type": "one", "delta": "1", "time": "2019", "type": "two", "delta": "1", "time": "2018"]', 'normalcol':2, 'weirdjsoncol':'["type": "two", "delta": "1", "time": "2017", "type": "one", "delta": "1", "time": "2013"]']

df = pd.DataFrame(data)

df['time_type_one'] = df['weirdjsoncol'].apply(lambda x: next((i for i in json.loads(x) if i["type"] == "one"), None)["time"])

df['time_type_two'] = df['weirdjsoncol'].apply(lambda x: next((i for i in json.loads(x) if i["type"] == "two"), None)["time"])

【讨论】:

不错,但是next 是干什么用的? 它是一个 Python 内置函数,用于从迭代器中检索下一项。你可以在 Python 文档中阅读它 - docs.python.org/3/library/functions.html#next 谢谢。这看起来不错。我想知道迭代是快还是慢。有什么想法吗?【参考方案2】:

你可以试试这个:

df_new = pd.DataFrame().append([x[y] for x in dftest.weirdjson for y in range(len(dftest.weirdjson))])
df_new = df_new.pivot(columns='type', values=['delta', 'time']).apply(lambda x: pd.Series(x.dropna().values)) 
df_new.columns = ['_'.join(col) for col in df_new.columns.values] 

  delta_one delta_two time_one time_two
0         1         1     2019     2018
1         1         1     2013     2017

【讨论】:

我更新了第二行,所以现在应该使用您的 dftest,我忘记了 df_new = 我不确定枢轴有多快,我可以在没有枢轴的情况下以另一种方式做到这一点,我将值聚合为列表并将它们展开,但这需要更多步骤,但行更短【参考方案3】:

您可以使用explode,并构造一个新的数据框和unstack 类型到列,如下所示:

s = dftest.weirdjson.explode()
df_new = (pd.DataFrame('type': s.str['type'], 'time': s.str['time']) 
            .set_index('type', append=True).time.unstack().add_prefix('time_type_'))

Out[461]:
type time_type_one time_type_two
0             2019          2018
1             2013          2012

【讨论】:

以上是关于如何有效地从 JSON 列中提取字段?的主要内容,如果未能解决你的问题,请参考以下文章

在 Oracle 中独立地从多个列中有效地查找前 N 个值

如何有效地从 Pandas 数据框移动到 JSON

简单地从firebase数据库中提取所有用户并将它们放入一个有效的数组中吗?

如何在 pySpark 中有效地从字符串数据框中替换多个正则表达式模式的所有实例?

BigQuery:如何获取列中特定字段的值?

BigQuery JSON 字段提取