我想在 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 列的主要内容,如果未能解决你的问题,请参考以下文章

从嵌套的 json 列表中展平 Pandas DataFrame

将嵌套的 dict 列表展平为 Pandas Dataframe

如何将 Pandas DataFrame 中的字典列表展平为几列?

Pandas Dataframe 根据列值将值展平到单元格

如何将 JSON 对象展平为 Pandas Dataframe 对象 [重复]

Pandas:如何从给定(行,列)对列表的 DataFrame 中检索值?