pandas.json_normalize是处理嵌套字典列表的正确方法,能自动展开层级、处理缺失值和混合类型,优于手动展平或直接dataframe构造。

用 pandas.json_normalize 处理嵌套字典列表最直接
多数人卡在 pd.DataFrame() 直接构造失败,因为嵌套结构里存在不等长的字典、None 值或混合类型字段。真正该用的是 pandas.json_normalize——它专为这种场景设计,能自动展开层级、处理缺失、生成带点号分隔的列名。
常见错误是把嵌套数据先手动递归展平再转 DataFrame,既易出错又慢。而 json_normalize 内部已优化过路径解析和空值填充逻辑。
- 对纯字典列表(无顶层 key),直接传入:
pd.json_normalize(data) - 若数据包在某个 key 下(如
{"results": [...]}),用record_path指定路径:pd.json_normalize(data, record_path="results") - 需要保留外层字段(如 metadata)时,配合
meta参数:pd.json_normalize(data, record_path="results", meta=["id", "timestamp"])
遇到 list-of-dict 字段时必须用 sep 和 max_level 控制展开深度
当某字段值本身是 [{"a": 1}, {"a": 2}] 这类列表时,默认行为会把整个 list 当作一个 object,列内容变成 [{"a": 1}, {"a": 2}] 而非两行。这时得靠 sep 和 max_level 显式控制。
默认 sep=".",但若原始字段名含点号(如 "user.id"),建议改用 sep="_" 避免歧义;max_level=0 表示只展开一级,适合想保留某些子结构的场景。
- 想把
"tags": [{"name": "A"}, {"name": "B"}]拆成两行?必须加record_path和meta组合:pd.json_normalize(data, record_path=["tags"], meta=[["user", "id"], ["post", "title"]]) - 字段名冲突(如外层和内层都有
"id")会导致列重名,json_normalize默认加后缀.0、.1,可提前 rename 或用errors="ignore"
空值、None 和缺失字段会让列类型变 object,需主动转换
json_normalize 对缺失字段统一填 None,导致整列 dtype 变成 object,后续算术运算或排序会报错。这不是 bug,而是为兼容任意嵌套结构做的保守设计。
别依赖 df.fillna().astype() 一刀切——不同列可能有不同合理默认值(比如时间字段填 pd.NaT,数值字段填 -1 或 np.nan)。
- 数值列:先
pd.to_numeric(df["col"], errors="coerce"),把非法字符串转为NaN - 时间列:用
pd.to_datetime(df["col"], errors="coerce"),无效值变NaT - 布尔列:注意
None无法直接转 bool,得先df["col"].map({True: True, False: False})或用astype("boolean")(pandas 1.0+)
超深嵌套(>5 层)或动态 key 名时,json_normalize 会失效
当嵌套超过 5–6 层,或 key 名本身是变量(如 {"2023-01": {...}, "2023-02": {...}}),json_normalize 的静态路径语法就力不从心了。这时候得退回到手动递归 + pd.json_normalize 分段处理。
典型陷阱是试图用正则匹配 key 名传给 record_path——它不支持通配符或 pattern,只认确切字符串或 list of strings。
- 动态日期 key:先用
{k: v for k, v in data.items() if k.startswith("20")}提取,再对每个 value 单独json_normalize - 混合结构(有些 item 有
"details",有些没有):先统一补全字段,或用errors="ignore"并接受部分列为None - 性能敏感场景:避免多次调用
json_normalize,优先用functools.reduce合并结果,而非pd.concat循环追加
真正麻烦的不是怎么展开,而是展开后字段语义是否还清晰——点号分隔的列名(如 user.profile.address.city)一旦超过三层,后续写分析代码就容易漏掉层级或拼错名字。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











