如何有效地从 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_one
和time_type_two
,每列都包含它们对应的time
值(第一行:2019
对应type one
,2018
对应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 列中提取字段?的主要内容,如果未能解决你的问题,请参考以下文章
简单地从firebase数据库中提取所有用户并将它们放入一个有效的数组中吗?