如何用json_normalize()规范化嵌套字段?嵌套列表JSON处理
解决嵌套JSON完整规范化的方案
不用手动指定大量字段的核心思路是结合pd.json_normalize的record_path和meta参数,既展开嵌套列表字段,又保留顶层的其他数据。如果要完全自动处理,可以写个小工具函数来自动识别顶层里的列表类型字段,批量处理。
1. 基础用法:手动指定要展开的嵌套列表(适合快速验证)
假设你的JSON数据结构大概是这样:
sample_json = [ { "id": 1, "name": "Region A", "territories": [ {"city": "Beijing", "code": "BJ"}, {"city": "Shanghai", "code": "SH"} ], "other_info": {"level": 1, "status": "active"} }, { "id": 2, "name": "Region B", "territories": [ {"city": "Guangzhou", "code": "GZ"} ], "other_info": {"level": 2, "status": "inactive"} } ]
直接用record_path指定要展开的嵌套列表territories,用meta指定需要保留的顶层字段(支持点语法展开顶层的嵌套对象,比如other_info.level):
import pandas as pd df = pd.json_normalize( sample_json, record_path="territories", meta=["id", "name", ["other_info", "level"], ["other_info", "status"]] )
这样得到的结果会把territories里的每个对象拆成一行,同时保留id、name、other_info里的字段,不会丢失任何数据。
2. 自动识别嵌套列表字段(无需手动指定)
如果JSON里有多个类似territories的嵌套列表字段,或者字段名不确定,可以写个函数自动检测顶层数据中的列表类型字段,然后批量处理:
def auto_normalize_json(json_data): if not json_data: return pd.DataFrame() # 获取第一个对象的所有键,判断哪些是列表类型 top_level_keys = list(json_data[0].keys()) list_fields = [key for key in top_level_keys if isinstance(json_data[0][key], list)] if not list_fields: # 没有嵌套列表,直接普通规范化 return pd.json_normalize(json_data) # 收集所有非列表的顶层字段(支持展开嵌套对象) meta_fields = [] for key in top_level_keys: if key not in list_fields: value = json_data[0].get(key) if isinstance(value, dict): # 嵌套对象的每个子字段都加入meta meta_fields.extend([[key, sub_key] for sub_key in value.keys()]) else: meta_fields.append(key) # 逐个展开列表字段(如果有多个,会依次展开) df = pd.DataFrame() for field in list_fields: temp_df = pd.json_normalize( json_data, record_path=field, meta=meta_fields, errors="ignore" ) # 标记当前展开的字段来源,避免多个列表字段展开后混淆 temp_df["_expanded_from"] = field df = pd.concat([df, temp_df], ignore_index=True) return df
调用这个函数处理上面的sample_json:
result_df = auto_normalize_json(sample_json)
它会自动识别territories是列表字段,展开的同时保留所有顶层和嵌套对象的字段,不用你手动一个个写meta参数。
3. 处理常见报错
- KeyError:通常是因为指定的
record_path或meta字段在某些JSON对象中不存在,解决方法是用get()方法替代直接取值,或者在meta里加入字段存在性判断。 - ValueError:如果JSON数据结构不一致(比如有的对象里
territories是列表,有的是None),可以在检测列表字段时过滤掉非列表的情况,或者在pd.json_normalize里加errors="ignore"参数。
内容的提问来源于stack exchange,提问作者Mitch
相关产品推荐
相关产品推荐

