You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pandas json_normalize触发Must be list or null TypeError的解决问询

问题解决:pandas json_normalize 处理嵌套JSON时的TypeError及缺失值填充

问题根源

触发TypeError的核心原因是:json_normalize的record_path参数要求对应路径的值必须是列表或null,但你的数据里loc对应的是字典类型,不符合要求。另外注意你示例中的JSON存在重复键g,Python字典会自动保留最后一个键值对,导致前面的g: {'value': '2.0', 'text': 'xxx'}被后面的g:[]覆盖,这会影响最终结果,需要先修正这个问题。

解决方案

1. 直接调整数据结构(若允许修改原始数据)

把loc对应的字典包装成列表,满足record_path的要求,同时处理重复键问题:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'id': [0, 1],
    'j': [
        {'type': 's', 'loc': [{'s': {'value': '0.0', 'text': 'xxx'}, 'ps': {'value': '0.0', 'text': 'xxx'}, 'g': {'value': '2.0', 'text': 'xxx'}}]},
        {'type': 's', 'loc': [{'s': {'value': '0.0', 'text': 'xxx'}, 'ps': {'value': '0.0', 'text': 'xxx'}, 'g': {'value': '2.0', 'text': 'xxx'}}]}
    ]
})

# 使用json_normalize,errors='ignore'忽略不存在的键
dff = pd.json_normalize(df['j'], record_path=['loc'], meta=['id'], errors='ignore')
# 空字符串或缺失值填充为np.nan
dff = dff.replace('', np.nan).fillna(np.nan)
print(dff)

2. 不修改原始数据的处理方式

如果无法调整原始数据,先对loc字段单独做字典扁平化,再合并id列:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'id': [0, 1],
    'j': [
        {'type': 's', 'loc': {'s': {'value': '0.0', 'text': 'xxx'}, 'ps': {'value': '0.0', 'text': 'xxx'}, 'g': {'value': '2.0', 'text': 'xxx'}}},
        {'type': 's', 'loc': {'s': {'value': '0.0', 'text': 'xxx'}, 'ps': {'value': '0.0', 'text': 'xxx'}, 'g': {'value': '2.0', 'text': 'xxx'}}}
    ]
})

# 扁平化每个loc字典
flattened_loc = df['j'].apply(lambda x: pd.json_normalize(x['loc'])).explode().reset_index(drop=True)
# 合并id列
dff = pd.concat([flattened_loc, df['id'].reset_index(drop=True)], axis=1)
# 填充缺失值
dff = dff.replace('', np.nan).fillna(np.nan)
print(dff)

3. 处理重复键的特殊情况

如果原始数据确实存在重复键,先用工具函数修复,将重复键的值合并为列表:

import pandas as pd
import numpy as np
from collections import defaultdict

def fix_duplicate_keys(obj):
    """修复JSON重复键,将同键值合并为列表"""
    if isinstance(obj, dict):
        new_obj = defaultdict(list)
        for k, v in obj.items():
            new_obj[k].append(fix_duplicate_keys(v))
        # 长度为1的列表转回原值
        return {k: v[0] if len(v)==1 else v for k, v in new_obj.items()}
    elif isinstance(obj, list):
        return [fix_duplicate_keys(item) for item in obj]
    else:
        return obj

# 修复数据中的重复键
df['j'] = df['j'].apply(fix_duplicate_keys)

# 扁平化并合并
flattened_loc = df['j'].apply(lambda x: pd.json_normalize(x['loc'])).explode().reset_index(drop=True)
dff = pd.concat([flattened_loc, df['id'].reset_index(drop=True)], axis=1)
dff = dff.replace('', np.nan).fillna(np.nan)
print(dff)

最终输出

运行上述代码后,将得到符合预期的结果:

s.value s.text ps.value ps.text g.value g.text  id
0     0.0    xxx      0.0    xxx     2.0    xxx   0
1     0.0    xxx      0.0    xxx     2.0    xxx   1

内容的提问来源于stack exchange,提问作者kms

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 14:27:08