整理存储在pandas单元格中的JSON列表

时间:2019-08-13 12:51:19

标签: python json pandas

我有一个pandas数据框,其中一列包含以字符串形式存储的JSON列表,但在尝试将其展平为列时遇到了麻烦。 JSON列如下所示

[{'id':'item1','xp':'27097','lvl':'26','items':[]},
{'id':'item2','xp':'40650','lvl':'26','items':[]},
{'id':'item3','xp':'33900','lvl':'26','items':['item1', 'item2', 'item3']}]

DF的屏幕截图(无法放置图片,信誉不足)https://i.imgur.com/1YNgXWE.png

json_normalize在这里不起作用,因为它是嵌套在pandas数据框中的字符串

预期结果:

+-----------+-------+-----+-----+-----------------------------+
| player_id |  id   | xp  | lvl |            items            |
+-----------+-------+-----+-----+-----------------------------+
| id1       | item1 | 444 |  10 | []                          |
| id1       | item2 |  12 |  77 | []                          |
| id1       | item3 |  15 |  20 | ['item1', 'item2', 'item3'] |
+-----------+-------+-----+-----+-----------------------------+

对于每个id,我想将此列表展平为culumns并获取项目及其参数的列表

以下代码适用于单个JSON,不适用于列表:

df = (pd.DataFrame([ast.literal_eval(x)[0] for x in original_df.pop('items')])
         .add_prefix('items.'))

2 个答案:

答案 0 :(得分:0)

由于我们没有原始数据,因此我不得不重新创建它,并假设它会像这样格式化。对此类对象执行pd.DataFrame(data)会在图像中产生相同的数据。

但是,然后,我正确使用了pandas.io.json.json_normalize,它起作用了。我只是无法绕过meta_prefix自变量,如果我要求,它应该剥离键的名称(“意思是,避免让'id'变成'items.id')。但是由于我无法使其工作,我只做了一个遍历各列并正确重命名它们的函数。

EDIT :由于items键是str而不是dict,所以我看到的唯一解决方案是将所有字符串都转换成字典。我前一段时间遇到了同样的问题,找不到其他解决方案。当时我对它进行了严格的基准测试,但是总体上它还是很快的。查看更新的代码。

import json
from pandas.io.json import json_normalize

data = [
    {
        'player_id' : 'id1',
        'items' : '{"id" : "item1", "xp" : "27097", "lvl" : "26", "items":[]}'
    },
    {
        'player_id' : 'id2',
        'items' : '{"id":"item2","xp":"40650","lvl":"26","items":[]}'
    },
    {
        'player_id' : 'id3',
        'items' : '{"id":"item3","xp":"33900","lvl":"26","items":["item1", "item2", "item3"]}'
    }
]

for idx in range(len(data)):
    data[idx]['items'] = json.loads(data[idx]['items'])

df = json_normalize(data, meta='items')
#  player_id items.id items.xp items.lvl            items.items
#0       id1    item1    27097        26                     []
#1       id2    item2    40650        26                     []
#2       id3    item3    33900        26  [item1, item2, item3]

prefix = 'items.'
df.columns = [col[len(prefix):] if col.startswith(prefix) else col for col in df.columns]

print(df)
#   player_id     id     xp lvl                  items
# 0       id1  item1  27097  26                     []
# 1       id2  item2  40650  26                     []
# 2       id3  item3  33900  26  [item1, item2, item3]

答案 1 :(得分:0)

我在这里回答。第1部分重新创建数据,第2部分回答问题

PART 1-创建数据集

unset($attr['placeholder'], $attr['autocomplete']);

PART 2-将这一系列Dict变成一个数据框

In [1]:
import pandas as pd
row_1 = "[{'id':'item1','xp':'27097','lvl':'26','items':[]}]"
row_2 = "[{'id':'item2','xp':'40650','lvl':'12','items':[]}]"
row_3 = "[{'id':'item3','xp':'33900','lvl':'45','items':['item1', 'item2', 'item3']}]"

data = {"My Dict":[row_1, row_2, row_3]}
df = pd.DataFrame(data)
df

Out [1]:
    My Dict
0   [{'id':'item1','xp':'27097','lvl':'26','items'...
1   [{'id':'item2','xp':'40650','lvl':'12','items'...
2   [{'id':'item3','xp':'33900','lvl':'45','items'...