我想在 Pandas DataFrame 中展平 JSON 列

Posted

技术标签:

【中文标题】我想在 Pandas DataFrame 中展平 JSON 列【英文标题】:I want to flatten JSON column in a Pandas DataFrame 【发布时间】:2018-09-24 03:51:05 【问题描述】:

我有一个输入数据框 df,如下所示:

id  e
1   "k1":"v1","k2":"v2"
2   "k1":"v3","k2":"v4"
3   "k1":"v5","k2":"v6"

我想“展平”列 'e',这样我的结果数据框是:

id  e.k1    e.k2
1   v1  v2
2   v3  v4
3   v5  v6

我该怎么做?我尝试使用 json_normalize 但没有太大成功

【问题讨论】:

【参考方案1】:

如果您的列还不是字典,您可以使用map(json.loads) 并应用pd.Series

s = df['e'].map(json.loads).apply(pd.Series).add_prefix('e.')

或者如果已经是字典,可以直接申请pd.Series

s = df['e'].apply(pd.Series).add_prefix('e.')

最后使用pd.concat 加入其他列:

>>> pd.concat([df.drop(['e'], axis=1), s], axis=1).set_index('id')    
id e.k1 e.k2
1    v1   v2
2    v3   v4
3    v5   v6

【讨论】:

【参考方案2】:

这里有一个使用pandas.io.json.json_normalize():的方法

from pandas.io.json import json_normalize
df = df.join(json_normalize(df["e"].tolist()).add_prefix("e.")).drop(["e"], axis=1)
print(df)
#  e.k1 e.k2
#0   v1   v2
#1   v3   v4
#2   v5   v6

但是,如果您的列实际上是 str 而不是 dict,那么您首先必须使用 json.loads() 对其进行映射:

import json
df = df.join(json_normalize(df['e'].map(json.loads).tolist()).add_prefix('e.'))\
    .drop(['e'], axis=1)

【讨论】:

您可能需要在df.join 之前df = df.reset_index() 以确保行匹配正确。 @pault 如果某些行对于带有 json 的列是空白的,您将如何采用此方法。您的解决方案适用于我,所有行都具有有效的 json,但如果我有任何带有空白列的行,我会收到错误:AttributeError: 'float' object has no attribute 'items'

以上是关于我想在 Pandas DataFrame 中展平 JSON 列的主要内容,如果未能解决你的问题,请参考以下文章