json_normalize能处理嵌套JSON是因为它将嵌套结构视为“路径”,用点号连接键名生成列名,并通过record_path和meta参数精准控制展开逻辑,支持sep、max_level等选项应对复杂场景。

json_normalize 为什么能处理嵌套 JSON
因为 json_normalize 不是简单地 flatten 字典,而是把嵌套结构看作“路径”,用点号(.)连接键名生成列名。比如 {"user": {"name": "Alice", "profile": {"age": 30}}} 会被展开成 user.name 和 user.profile.age 两列。它默认只展开一层,但通过 record_path 和 meta 参数可以精准控制哪部分当主记录、哪部分当附加字段。
record_path + meta 组合用法必须写对
常见错误是直接传整个嵌套字典给 json_normalize,结果得到一堆空列或报 KeyError。正确做法是先定位数据主体:如果 JSON 中有个叫 data 的列表,里面每项是带 id、details(又含 price 和 tags)的对象,就得这样写:
df = json_normalize(
data=json_data,
record_path=['data', 'details'], # 指向嵌套列表路径
meta=['id', ['data', 'category']] # 提取上层字段,嵌套字段用列表表示
)注意:record_path 必须指向一个列表(不是字典),否则会报 TypeError: record_path not a list;meta 里写 ['user', 'name'] 表示从当前记录的父级往上找两级。
处理含列表字段的嵌套数据要加 sep 和 max_level
当某个字段值本身是列表(如 "tags": ["a", "b"]),json_normalize 默认会把它转成字符串 "['a', 'b']",而不是展开成多行。如果你需要“一行变多行”,得配合 pd.json_normalize + explode;如果只是想避免点号冲突,用 sep='_' 替换默认的 . 更安全。另外,深层嵌套(比如 5 层)可能生成超长列名,设 max_level=2 可截断,防止列名爆炸。
立即学习“Python免费学习笔记(深入)”;
-
sep='_'推荐在字段名含点号或需兼容数据库列名时使用 -
max_level=1适合只要最外两层、忽略更深结构的场景 - 含列表字段不手动
explode,就别指望它自动“打散”成多行
遇到 null 或缺失键时列会变 object 类型
json_normalize 遇到某条记录缺 address.city,对应列就会混入 None,导致整列 dtype 变成 object,后续数值计算容易出错。解决办法有两个:
- 初始化时加
errors='ignore'(但会静默丢数据) - 更稳妥的是先用
pd.json_normalize(..., errors='raise')检查结构一致性,再用df.fillna()或df.astype()显式转换类型 - 如果某些嵌套路径完全不存在,考虑预处理:用
jsonpath-ng或递归函数补全空字段
嵌套 JSON 转表格真正的难点不在调用函数,而在理解原始结构是否规整——不规整的数据,json_normalize 顶多帮你展平,填不了逻辑空洞。


















