使用Pandas json_normalize时嵌套Meta字段返回NaN的原因解析
Pandas json_normalize meta参数逻辑解析及问题修复
问题重现
给定如下类JSON结构的Python字典:
d = { "type": "type1", "details": { "name": "foo", "date": { "timestamp": "01/02/2023 21:42:44", "components": { "day": 2, "month": 1, "year": 2023, "time": "21:42:44" } } }, "infos": { "records": [ { "field1": "qux", "field2": "baz", } ], "class": "P" } }
使用以下代码进行JSON扁平化:
import pandas as pd df = pd.json_normalize( d, record_path=["infos", "records"], meta=[ "type", ["details", "date", "timestamp"], ["details", "date", "components", "year"], ["infos", "class"] ], errors="ignore" )
实际输出(部分字段为NaN):
field1 field2 type details.date.timestamp details.date.components.year infos.class 0 qux baz type1 NaN NaN P
期望输出:
field1 field2 type details.date.timestamp details.date.components.year infos.class 0 qux baz type1 01/02/2023 21:42:44 2023 P
问题原因及meta参数逻辑解析
json_normalize的meta参数路径规则取决于Pandas版本和输入数据结构:
- Pandas 1.0+版本:当输入为单个字典,且
record_path指向字典内的嵌套数组时,meta路径是相对于整个JSON的根节点的,原代码的路径写法是正确的。如果出现NaN,大概率是Pandas版本过低。 - Pandas 0.25及更早版本:此时
meta路径是相对于record_path的父节点(即示例中的infos层级)。原代码中type、details等字段属于根节点,从infos层级无法直接访问,因此返回NaN;而infos.class能正常获取,是因为它和records同属infos层级。
修复方案
方案1:升级Pandas到1.0+
直接使用原代码即可得到期望输出,无需修改路径。
方案2:适配旧版本Pandas(使用相对路径)
通过../(或列表形式的["..", ...])表示向上跳转父级节点,指向根层级的字段:
df = pd.json_normalize( d, record_path=["infos", "records"], meta=[ "../type", "../details/date/timestamp", "../details/date/components/year", "class" # class与records同属infos层级,直接写键名 ], errors="ignore" )
或使用列表形式的相对路径:
df = pd.json_normalize( d, record_path=["infos", "records"], meta=[ ["..", "type"], ["..", "details", "date", "timestamp"], ["..", "details", "date", "components", "year"], ["class"] ], errors="ignore" )
运行上述代码后,即可得到期望的输出结果。
内容的提问来源于stack exchange,提问作者user21474411
相关产品推荐
相关产品推荐

