提问人:cobonthecorn 提问时间:8/17/2023 最后编辑:Andrej Keselycobonthecorn 更新时间:8/17/2023 访问量:40
从复杂的嵌套字典(各种深度)和字典列表创建 DataFrame
Creating a DataFrame from a complex nested dictionary (various depths) and lists of dictionaries
问:
我有一个 API 调用,它使用不同级别的嵌套字典进行响应。对于任何误用的术语或任何事情,我提前道歉,因为虽然我在一般的数据整理方面有很好的经验,但复杂的词典并不是我太熟悉的东西。我正在尝试创建一个数据框,该数据框将每个级别和属性作为列。列“Level0”、“Level1”等的级别值是字典中每个级别的“@name”键的值。属性列名是“@name”键的值,这些列的值在“@value”中。
以下是字典的片段:
dct={'@id': '21',
'@name': 'Top Level',
'@hasChildren': 'true',
'level': [{'@id': '22',
'@name': 'Asset1',
'@hasChildren': 'true',
'level': [{'@id': '530',
'@name': 'Sub Asset1-1',
'attributes': {'attribute': [{'@attributeId': '1581',
'@name': 'Grouping',
'@value': 'Tall'},
{'@attributeId': '1141',
'@name': 'Asset Reporting',
'@value': 'Public'},
{'@attributeId': '981',
'@name': 'Unit',
'@value': 'Tons'}]}},
{'@id': '101',
'@name': 'Asset2',
'@hasChildren': 'true',
'level': [{'@id': '123',
'@name': 'Sub Asset2-1',
'@hasChildren': 'true',
'level': [{'@id': '1061',
'@name': 'Store 2-1-1',
'@hasChildren': 'true',
'level': [{'@id': '205',
'@name': 'Shelf 23',
'attributes': {'attribute': [{'@attributeId': '581',
'@name': 'Type',
'@value': 'Shirt'},
{'@attributeId': '1161',
'@name': 'Region',
'@value': 'USA'},
{'@attributeId': '1261',
'@name': 'Area_Grouping',
'@value': 'East Coast'},
{'@attributeId': '1581',
'@name': 'Grouping',
'@value': 'Short'},
{'@attributeId': '1141',
'@name': 'Asset Reporting',
'@value': 'Consolidated'},
{'@attributeId': '981',
'@name': 'Unit',
'@value': 'Feet'}]}},
{'@id': '213',
'@name': 'Shelf 49',
'attributes': {'attribute': [{'@attributeId': '581',
'@name': 'Type',
'@value': 'Pants'},
{'@attributeId': '1161',
'@name': 'Region',
'@value': 'USA'},
{'@attributeId': '1261',
'@name': 'Area_Grouping',
'@value': 'West Coast'},
{'@attributeId': '1581',
'@name': 'Grouping',
'@value': 'Short'},
{'@attributeId': '1141',
'@name': 'Asset Reporting',
'@value': 'Consolidated'},
{'@attributeId': '981',
'@name': 'Unit',
'@value': 'Feet'}]}}
'attributes': {'attribute': {'@attributeId': '841',
'@name': 'Consolidated Reporting',
'@value': 'Consolidated'}}}
我试图最终得到一个如下所示的数据框(由于大小格式而截断属性):
Level0 |Level1 |Level2 |Level3 |Level4
|Grouping|Asset Reporting
Top Level | | | | | |
Top Level |Asset1 |Sub Asset1-1 | | |Tall |Public
Top Level |Asset2 |Sub Asset2-1 |Store 2-1-1 |Shelf 23 | |Consolidated
Top Level |Asset2 |Sub Asset2-1 |Store 2-1-1 |Shelf 49 |Short |Consolidated
经过许多不同的努力,我现在无法重新创建,我开始从这里获得帮助(参见 1.6),但我仍然只是得到一个字典,我无法弄清楚如何将其工作到数据帧中。
def get_all_values(obj, level=0):
"""Walk through a dictionary of dicts and lists."""
if type(obj) is dict:
for key, value in obj.items():
if type(value) in [dict, list]:
print('\t' * level, key, sep='')
level = level + 1
get_all_values(value, level)
level = level - 1
else:
print('\t' * (level), key, ': ', value, sep='')
elif type(obj) is list:
for i, element in enumerate(obj):
if type(element) in [dict, list]:
print('\t' * level, i, sep='')
level = level + 1
get_all_values(element, level)
level = level - 1
else:
print('\t' * (level), element, sep='')
else:
raise ValueError
我还尝试过使用 .explode() 和 pd 的组合。系列后将其放入数据帧中,但觉得最好在数据帧之前做更多的工作。
答:
0赞
Tranbi
8/17/2023
#1
示例数据的语法无效。我关闭了括号,但我作为一个孩子......无论如何,这与隐含的逻辑无关。Asset2
Asset1
使用递归函数是正确的方法:
import pandas as pd
def get_all_values(obj):
res = []
def get_level(obj, level=0, r={}):
if type(obj) is dict:
if n:=obj.get('@value', obj.get('@name')):
r[f'Level{level}'] = n
if l:=obj.get('level', obj.get('attributes', obj.get('attribute'))):
r.update(get_level(l, level+1, r.copy()))
elif type(obj) is list:
bottom = False
for element in obj:
if isinstance(element, dict):
if '@value' in element:
r[element['@name']] = element['@value']
bottom = True
else:
r[f'Level{level}'] = element.get('@name')
r.update(get_level(element, level, r.copy()))
if bottom:
res.append(r)
return r
get_level(obj)
return res
print(pd.DataFrame(get_all_values(dct)))
输出:
Level0 Level1 Level2 Grouping Asset Reporting Unit Level3 Level4 Level5 Type Region Area_Grouping
0 Top Level Asset1 Sub Asset1-1 Tall Public Tons NaN NaN NaN NaN NaN NaN
1 Top Level Asset1 Asset2 Short Consolidated Feet Sub Asset2-1 Store 2-1-1 Shelf 23 Shirt USA East Coast
2 Top Level Asset1 Asset2 Short Consolidated Feet Sub Asset2-1 Store 2-1-1 Shelf 49 Pants USA West Coast
上一个:打印特定的嵌套值项
评论