使用 normalize 展平三重嵌套 JSON
Posted
技术标签:
【中文标题】使用 normalize 展平三重嵌套 JSON【英文标题】:Flatten triple-nested JSON with normalize 【发布时间】:2019-12-10 02:59:09 【问题描述】:我正在尝试展平以下内容,但它仅适用于非三重嵌套 JSON。
工作代码:
导入 json
import pandas as pd
from pandas.io.json import json_normalize
data = ['masterName': 'AAAAAAAAAAA',
'shortname': 'AA',
'info':
'name': 'randomka'
,
'mainNames': ['date': '2019-05-16', 'NumberOne': 1111,
'date': '2019-06-22', 'NumberOne': 2222]
]
result = json_normalize(data, 'mainNames', ['masterName', 'shortname',
['info', 'name']],errors='ignore')
不工作:
data2 = ["masterName": "AAAAAAAAAAA",
"mainNames": [
"numbers": [
"date": "2019-05-16",
"NumberOne": 222],
"name": "randomka"
,
"numbers": [
"date": "2019-05-16",
"NumberOne": 222],
"name": "randomka"
]
]
json_normalize(data2, 'mainNames', ['masterName'],errors='ignore')
返回时:
我在json_normalize
代码中尝试了替代record_paths
和metas
,但我无法使其适用于这个三重嵌套的JSON。换句话说,我不能一口气读完所有的专栏。
我尝试过的替代方案很有效并且看起来很接近:
json_normalize(data2, ['mainNames','numbers'], ['masterName'],errors='ignore')
输出几乎是一个 Excel 视图,其中包含列中的数据。根据评论请求的预期视图:
UPD:数据可能有多个数字分支:
data2 = ["masterName": "AAAAAAAAAAA",
"mainNames": [
"numbers": [
"date": "2019-05-16",
"NumberOne": 222],
"name": "randomka"
,
"numbers": [
"date": "2019-05-16",
"NumberOne": 222,
"date": "2019-07-01",
"NumberOne": 341],
"name": "randomka"
]
]
【问题讨论】:
你能分享一下预期的输出吗?我不熟悉这个过程正常化。我敢肯定,分享预期的输出也会对其他人有所帮助。无论如何,为这个问题制作自己的功能是否可以接受?我觉得这可能需要更少的时间。 【参考方案1】:正如@Aayush Mahajan 在 cmets 中所建议的那样,定义自己的函数可能更简单。这是一个与data2
合作的人:
out = []
data2 = data2[0] # Remove first level
for main in data2["mainNames"]: # Iterate "mainNames"
sub_dict = "masterName": data2['mainNames'] # Init new dict (df row) with "mainNames"
sub_dict.update(main["numbers"][0]) # Add all fields from "numbers"
sub_dict["name"] = main["name"] # Add "name" field
out.append(sub_dict) # append sud dict to list outputs
print(out)
# ['masterName': 'AAAAAAAAAAA', 'date': '2019-05-16', 'NumberOne': 222, 'name': 'randomka',
# 'masterName': 'AAAAAAAAAAA', 'date': '2019-05-16', 'NumberOne': 222, 'name': 'randomka']
# create Dataframe with from_dict
df = pd.DataFrame().from_dict(out)
print(df)
# masterName date NumberOne name
# 0 AAAAAAAAAAA 2019-05-16 222 randomka
# 1 AAAAAAAAAAA 2019-05-16 222 randomka
更新:
您可以添加一个内部 loop
来迭代 numbers
字段:
out = []
data2 = data2[0] # Remove first level
for main in data2["mainNames"]: # Iterate "mainNames"
for numbers in main["numbers"]:
sub_dict = "masterName": data2['masterName'] # Init new dict (df row) with "mainNames"
sub_dict.update(numbers) # Add all fields from "numbers"
sub_dict["name"] = main["name"] # Add "name" field
out.append(sub_dict) # append sud dict to list outputs
print(out)
# ['masterName': 'AAAAAAAAAAA', 'date': '2019-05-16', 'NumberOne': 222, 'name': 'randomka',
# 'masterName': 'AAAAAAAAAAA', 'date': '2019-05-16', 'NumberOne': 222, 'name': 'randomka',
# 'masterName': 'AAAAAAAAAAA', 'date': '2019-07-01', 'NumberOne': 341, 'name': 'randomka']
df = pd.DataFrame().from_dict(out)
print(df)
# NumberOne date masterName name
# 0 222 2019-05-16 AAAAAAAAAAA randomka
# 1 222 2019-05-16 AAAAAAAAAAA randomka
# 2 341 2019-07-01 AAAAAAAAAAA randomka
同样,它仍在使用初始的data2
。
希望有帮助!
【讨论】:
当有多个数字数组时不起作用。 @Apolo Radomer 我根据您提供的样本回答。如果您的数据实际上不同,请分享最坏的情况或添加详细信息。 我尝试使用 for 循环进行很多更改,但对我不起作用。我已经用更新的 JSON 更新了问题。 我是如此接近。我在循环之外有sub_dict = "masterName": data2['masterName']
。以上是关于使用 normalize 展平三重嵌套 JSON的主要内容,如果未能解决你的问题,请参考以下文章
Pandas json_normalize 不会展平所有嵌套字段
pandas json_normalize 所有列都有嵌套字典展平