gpt4 book ai didi

python - 使用 pd.json_normalize 展平字典

转载 作者:行者123 更新时间:2023-12-01 23:29:55 25 4
gpt4 key购买 nike

我目前正在对这个字典文件进行扁平化处理,遇到了一些障碍。我正在尝试使用 json_normalize 来展平这些数据。如果我对单个实例进行测试,它可以工作,但如果我想展平所有数据,它将返回一个错误,指出 key error '0' 我不确定如何解决这个问题。

数据示例-

data = {1:{
'Name': "Thrilling Tales of Dragon Slayers",
'IDs':{
"StoreID": ['123445452543'],
"BookID": ['543533254353'],
"SalesID": ['543267765345']},
2:{
'Name': "boring Tales of Dragon Slayers",
'IDs':{
"StoreID": ['111111', '1121111'],
"BookID": ['543533254353', '4324232342'],
"SalesID": ['543267765345', '4353543']}}

我的代码

d_flat = pd.io.json.json_normalize(data, meta=['Title', 'StoreID', 'BookID', 'SalesID'])

最佳答案

设置

您的数据结构不便。我想关注:

  1. 'IDs' 中的列表放入字典列表中,这样会方便得多。
  2. 删除父字典中无用的键。我们只关心值(value)观。

您的数据:

{1: {'Name': 'Thrilling Tales of Dragon Slayers',
'IDs': {'StoreID': ['123445452543'],
'BookID': ['543533254353'],
'SalesID': ['543267765345']}},
2: {'Name': 'boring Tales of Dragon Slayers',
'IDs': {'StoreID': ['111111', '1121111'],
'BookID': ['543533254353', '4324232342'],
'SalesID': ['543267765345', '4353543']}}}

我希望它看起来像什么:

[{'Name': 'Thrilling Tales of Dragon Slayers',
'IDs': [{'StoreID': '123445452543',
'BookID': '543533254353',
'SalesID': '543267765345'}]},
{'Name': 'boring Tales of Dragon Slayers',
'IDs': [{'StoreID': '111111',
'BookID': '543533254353',
'SalesID': '543267765345'},
{'StoreID': '1121111',
'BookID': '4324232342',
'SalesID': '4353543'}]}]

重构数据

合理方式

简单的循环,不要乱来。这让我们得到了我上面展示的内容

new = []

for v in data.values():
temp = {**v} # This is intended to keep all the other data that might be there
ids = temp.pop('IDs') # I have to focus on this to create the records
temp['IDs'] = [dict(zip(ids, x)) for x in zip(*ids.values())]
new.append(temp)

可爱的单线

new = [{**v, 'IDs': [dict(zip(v['IDs'], x)) for x in zip(*v['IDs'].values())]} for v in data.values()]

使用pd.json_normalize创建DataFrame

在调用 json_normalize 时,我们需要指定记录的路径,即在 'IDs' 键中找到的 id 字典列表。 json_normalize 将为该列表中的每个项目在数据框中创建一行。这将通过 record_path 参数完成,我们传递一个 tuple 来描述路径(如果它在更深的结构中)或一个字符串(如果键在顶层,对我们来说就是顶层)。

record_path = 'IDs'

然后我们要告诉 json_normalize 哪些键是记录的元数据。如果像我们一样有多个记录,那么元数据将为每条记录重复。

meta = 'Name'

所以最终的解决方案是这样的:

pd.json_normalize(new, record_path='IDs', meta='Name')

StoreID BookID SalesID Name
0 123445452543 543533254353 543267765345 Thrilling Tales of Dragon Slayers
1 111111 543533254353 543267765345 boring Tales of Dragon Slayers
2 1121111 4324232342 4353543 boring Tales of Dragon Slayers

然而

如果我们无论如何都要重组,不妨进行重组,这样我们就可以将其传递给数据框构造函数。

pd.DataFrame([
{'Name': r['Name'], **dict(zip(r['IDs'], x))}
for r in data.values() for x in zip(*r['IDs'].values())
])

Name StoreID BookID SalesID
0 Thrilling Tales of Dragon Slayers 123445452543 543533254353 543267765345
1 boring Tales of Dragon Slayers 111111 543533254353 543267765345
2 boring Tales of Dragon Slayers 1121111 4324232342 4353543

奖励内容

当我们在做的时候。关于每个 id 类型是否具有相同数量的 id,数据是不明确的。假设他们没有。

data = {1:{
'Name': "Thrilling Tales of Dragon Slayers",
'IDs':{
"StoreID": ['123445452543'],
"BookID": ['543533254353'],
"SalesID": ['543267765345']}},
2:{
'Name': "boring Tales of Dragon Slayers",
'IDs':{
"StoreID": ['111111', '1121111'],
"BookID": ['543533254353', '4324232342'],
"SalesID": ['543267765345', '4353543', 'extra id']}}}

然后我们可以使用 itertools 中的 zip_longest

from itertools import zip_longest

pd.DataFrame([
{'Name': r['Name'], **dict(zip(r['IDs'], x))}
for r in data.values() for x in zip_longest(*r['IDs'].values())
])

Name StoreID BookID SalesID
0 Thrilling Tales of Dragon Slayers 123445452543 543533254353 543267765345
1 boring Tales of Dragon Slayers 111111 543533254353 543267765345
2 boring Tales of Dragon Slayers 1121111 4324232342 4353543
3 boring Tales of Dragon Slayers None None extra id

关于python - 使用 pd.json_normalize 展平字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66464851/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com