Pandas 跨记录扩展 json 字段

Posted

技术标签:

【中文标题】Pandas 跨记录扩展 json 字段【英文标题】:Pandas expand json field across records 【发布时间】:2014-10-20 03:06:49 【问题描述】:

我有一个有趣的问题,我想知道是否有一种简洁、pythonic(pandastic?)的方法来做到这一点,而不是遍历数据框的行。

获取一个数据帧,其中一个字段是信息的 json 编码:

    Name      Data
0   Joe       '["label":"a","value":"1","label":"b","value":"2"]'
1   Sue       '["label":"a","value":"3","label":"c","value":"4"]'
2   Bob       '["label":"b","value":"4","label":"d","value":"1"]'

我想将json字段扩展为数据字段,合并不同的列标题,得到这个:

    Name      Data                 a    b    c    d
0   Joe       '["label":"a"...    1    2    
1   Sue       '["label":"a"...    3         4
2   Bob       '["label":"b"...         4         1

空格是缺失值。我知道我可以使用 read_json 从 json 字段创建数据帧,但是我想将这些数据帧重新展平为原始数据集的额外列。

那么,有没有一种优雅的方法可以在不遍历数据框的各个行的情况下做到这一点?任何帮助将不胜感激。

【问题讨论】:

字符串 'a:1,b:2' 不是有效的 JSON。这真的是你所拥有的,还是可以用json.loads 解码实际值? 谢谢,我又快又马虎了。我已经重做了这个问题,以获得与问题相对应的正确 json。 【参考方案1】:

给定

In [96]: df
Out[96]: 
  Name                   Data
0  Joe  ["a":"1","b":"2"]
1  Sue  ["a":"3","c":"4"]
2  Bob  ["b":"4","d":"1"]

如果你定义

import json
def json_to_series(text):
    keys, values = zip(*[item for dct in json.loads(text) for item in dct.items()])
    return pd.Series(values, index=keys)

然后

In [97]: result = pd.concat([df, df['Data'].apply(json_to_series)], axis=1)

In [98]: result
Out[98]: 
  Name                   Data    a    b    c    d
0  Joe  ["a":"1","b":"2"]    1    2  NaN  NaN
1  Sue  ["a":"3","c":"4"]    3  NaN    4  NaN
2  Bob  ["b":"4","d":"1"]  NaN    4  NaN    1

给定

In [22]: df
Out[22]: 
  Name                                               Data
0  Joe  ["label":"a","value":"1","label":"b","value...
1  Sue  ["label":"a","value":"3","label":"c","value...
2  Bob  ["label":"b","value":"4","label":"d","value...

如果你定义

def json_to_series(text):
    keys, values = zip(*[(dct['label'], dct['value']) for dct in json.loads(text)])
    return pd.Series(values, index=keys)

然后

In [20]: result = pd.concat([df, df['Data'].apply(json_to_series)], axis=1)

In [21]: result
Out[21]: 
  Name                                               Data    a    b    c    d
0  Joe  ["label":"a","value":"1","label":"b","value...    1    2  NaN  NaN
1  Sue  ["label":"a","value":"3","label":"c","value...    3  NaN    4  NaN
2  Bob  ["label":"b","value":"4","label":"d","value...  NaN    4  NaN    1

参考资料:

list comprehensions the * unpacking operator zip

【讨论】:

非常感谢 unutbu -- 这太棒了。调整代码是否很容易,以便它适用于我在修改后的问题中提供的输入,并且列标题包含在 json 中? 当然。你只需要一点点改变。这里使用的工具需要一些时间来解释。我认为文档比我做得更好。所以我留下了一些参考链接;如果您有任何问题,请随时提出。

以上是关于Pandas 跨记录扩展 json 字段的主要内容,如果未能解决你的问题,请参考以下文章

使用某些字段查找重复记录并使用 Pandas 库更改字段值

从大型 JSON 中读取特定字段并导入 Pandas 数据框

Pandas json_normalize 不会展平所有嵌套字段

访问帮助以动态确定跨字段的记录日期更改

是否有内置函数可以跨所有记录获取数组字段中的所有唯一值?

python pandas:过滤掉给定字段的空字符串或空字符串的记录