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

如何使用Pandas动态归一化深度嵌套JSON/字典?

用Pandas动态处理嵌套JSON的json_normalize方案

先修正硬编码的错误写法

你当前代码的meta参数使用逻辑错误:record_path=["test","broodje"]指向的是test数组元素下的broodje数组,此时landje是test数组元素的字段,而coupon、days_due等是broodje元素本身的字段,不需要放到meta里。另外aap是broodje里的嵌套数组,需要额外处理。

正确的硬编码处理步骤如下:

import pandas as pd
from pandas import json_normalize

data = {
   "test": [
       {
           "landje": "ES",
           "broodje": [
               {"coupon": "abcde", "aap": [{"type": "dirk", "dirk_code": "1234"}], "days_due": ["1"]},
               {"coupon": "zxcv", "aap": [{"type": "dirk", "dirk_code": "2345"}], "days_due": ["2"]}
           ]
       },
       {
           "landje": "FR",
           "broodje": [
               {"coupon": "ergd", "aap": [{"type": "dirk", "dirk_code": "4567"}], "days_due": ["3"]},
               {"coupon": "tygh", "aap": [{"type": "dirk", "dirk_code": "7789"}], "days_due": ["4"]}
           ]
       }
   ]
}

# 第一步:处理test -> broodje的层级,提取landje作为元数据
df_level1 = json_normalize(data["test"], record_path="broodje", meta="landje")

# 第二步:处理broodje下的aap嵌套数组
df_aap = json_normalize(df_level1["aap"].explode().tolist())

# 第三步:处理days_due单元素数组,提取值
df_days = df_level1["days_due"].str[0].rename("days_due")

# 合并所有结果
df_final = pd.concat([df_level1.drop(columns=["aap", "days_due"]), df_aap, df_days], axis=1)

# 调整列顺序(可选)
df_final = df_final[["landje", "coupon", "type", "dirk_code", "days_due"]]
print(df_final)

运行后会得到符合预期的结果:

landje coupon   type dirk_code days_due
0     ES  abcde   dirk      1234        1
1     ES   zxcv   dirk      2345        2
2     FR   ergd   dirk      4567        3
3     FR   tygh   dirk      7789        4

实现动态配置方案

通过定义配置字典指定各层级的处理规则,无需硬编码路径和字段:

1. 定义配置结构

配置字典包含根路径、主记录路径、元数据字段、嵌套字段的处理规则:

config = {
    "root_path": "test",  # 顶层数组的键名
    "main_record_path": "broodje",  # 需要展开的主数组字段
    "meta_fields": ["landje"],  # 需要保留的上层元数据字段
    "nested_fields": {
        # 处理aap嵌套数组:展开并提取内部字段
        "aap": {
            "is_array": True,
            "extract_fields": True
        },
        # 处理days_due单元素数组:直接提取第一个元素
        "days_due": {
            "is_array": True,
            "extract_first": True
        }
    }
}

2. 编写动态处理函数

根据配置自动完成嵌套JSON的归一化:

def dynamic_json_normalize(data, config):
    # 获取顶层数据
    root_data = data[config["root_path"]]
    
    # 第一层归一化:展开主记录数组并保留元数据
    df = json_normalize(root_data, record_path=config["main_record_path"], meta=config["meta_fields"])
    
    # 遍历处理所有嵌套字段
    for field, settings in config["nested_fields"].items():
        if field not in df.columns:
            continue
        
        if settings["is_array"]:
            if settings.get("extract_first"):
                # 提取数组第一个元素
                df[field] = df[field].str[0]
            elif settings.get("extract_fields"):
                # 展开嵌套数组并提取内部字段
                nested_df = json_normalize(df[field].explode().tolist())
                df = pd.concat([df.drop(columns=[field]), nested_df], axis=1)
    
    return df

3. 使用动态函数

调用函数即可完成动态归一化:

df_dynamic = dynamic_json_normalize(data, config)
# 可选:调整列顺序
df_dynamic = df_dynamic[["landje", "coupon", "type", "dirk_code", "days_due"]]
print(df_dynamic)

后续如果JSON结构变化,只需要修改配置字典,无需修改核心处理代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 11:12:13