我有一个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.'))
答案 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部分回答问题
unset($attr['placeholder'], $attr['autocomplete']);
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'...