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

如何用Python高效展平含多嵌套数组的复杂JSON?

解决嵌套JSON同时展平多数组字段的问题

我在stackoverflow、geeksforgeeks等平台折腾了好几个小时,想把嵌套JSON展平,但用json_normalize()、flatten_json这些工具都没得到想要的结果。

JSON示例

[
    {
        'id': '7064574404',
        'type': 'INDIVIDUAL',
        'name': {'first': 'John', 'middle': 'A.', 'last': 'Doe'},
        'addresses': [
            {'address': '774 Pony Ct', 'city': 'Aberdeen', 'state': 'IA', 'zip': '77445', 'phone': '8007777777'},
            {'address': '776 S Adams St', 'city': 'Gray Mane', 'state': 'CA', 'zip': '22074', 'phone': '8882384677'},
            {'address': '745 E Stallion Ave', 'city': 'White Mane', 'state': 'CA', 'zip': '22074', 'phone': '2234846627'},
            {'address': '745 E Stallion Ave', 'city': 'White Mane', 'state': 'CA', 'zip': '22074', 'phone': '2234846627'},
            {'address': '757 W Saint George Ave', 'city': 'Mustang', 'state': 'CA', 'zip': '22840', 'phone': '2234645662'},
            {'address': '757 W Saint George Ave', 'city': 'Mustang', 'state': 'CA', 'zip': '22840', 'phone': '2234645662'}
        ],
        'specialty': ['Internal Medicine'],
        'accepting': 'accepting',
        'plans': [
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740007', 'network_tier': 'NETWORK', 'years': [7077, 7074]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740007', 'network_tier': 'NETWORK', 'years': [7077]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740004', 'network_tier': 'NETWORK', 'years': [7077, 7074]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740004', 'network_tier': 'NETWORK', 'years': [7077, 7074]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740006', 'network_tier': 'NETWORK', 'years': [7077]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740007', 'network_tier': 'NETWORK', 'years': [7077, 7074]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740008', 'network_tier': 'NETWORK', 'years': [7077, 7074]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740009', 'network_tier': 'NETWORK', 'years': [7077]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740070', 'network_tier': 'NETWORK', 'years': [7077]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740077', 'network_tier': 'NETWORK', 'years': [7074]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740077', 'network_tier': 'NETWORK', 'years': [7074]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740074', 'network_tier': 'NETWORK', 'years': [7074]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740070', 'network_tier': 'NETWORK', 'years': [7077, 7074]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740077', 'network_tier': 'NETWORK', 'years': [7077, 7074]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740074', 'network_tier': 'NETWORK', 'years': [7077, 7074]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740075', 'network_tier': 'NETWORK', 'years': [7077, 7074]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740076', 'network_tier': 'NETWORK', 'years': [7077, 7074]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740077', 'network_tier': 'NETWORK', 'years': [7077, 7074]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740079', 'network_tier': 'NETWORK', 'years': [7077, 7074]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740040', 'network_tier': 'NETWORK', 'years': [7077]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740047', 'network_tier': 'NETWORK', 'years': [7077]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740040', 'network_tier': 'NETWORK', 'years': [7074]},
            {'plan_id_type': 'HIOS-PLAN-ID', 'plan_id': '70774CA0740047', 'network_tier': 'NETWORK', 'years': [7074]}
        ],
        'languages': ['English'],
        'gender': 'Male',
        'last_updated_on': '2019-07-12'
    }
]

需求说明

我要把name(first、middle、last)、addresses(address、city、state、zip、phone)、plans(plan_id_type、plan_id、network_tier、years,years无需拆分)都拆成单独列,最终导出成易读的CSV。我能单独用json_normalize处理addresses和plans,但没法同时处理这两个数组,求解决办法。

我尝试过的代码

df2 = pd.json_normalize(
    data, "addresses", ["id", "type", "specialty", "accepting", ["name", "first"], ["name", "middle"], ["name", "last"]]
)
df2

df3 = pd.json_normalize(
    data, "plans", ["id", "type", "specialty", "accepting", ["name", "first"], ["name", "middle"], ["name", "last"]]
)
df3

解决方案

因为addresses和plans都是多值数组,直接同时展平会生成笛卡尔积(每个地址对应每个计划),这是符合业务逻辑的——每个医生的每个地址都需要关联其所有可用计划。具体步骤如下:

步骤1:处理顶层嵌套字段(name)

先把name的子字段提取为单独列,保留所有顶层信息:

import pandas as pd

# 假设data是你的JSON数据列表
df_base = pd.json_normalize(data)
# 提取name的子字段并合并到主表,删除原name列
df_base = df_base.join(df_base.pop('name').apply(pd.Series))

步骤2:分别展平addresses和plans数组

单独展平两个数组,保留关联的唯一标识id,方便后续合并:

# 展平addresses数组,关联id
df_addresses = pd.json_normalize(data, 'addresses', ['id'])
# 展平plans数组,关联id
df_plans = pd.json_normalize(data, 'plans', ['id'])

步骤3:合并所有表得到最终结果

通过id将三个表关联,生成完整的展平数据,最后导出CSV:

# 合并基础表和地址表
df_combined = pd.merge(df_base, df_addresses, on='id', how='left')
# 再合并计划表,得到所有地址与计划的关联数据
df_final = pd.merge(df_combined, df_plans, on='id', how='left')

# 删除不需要的原数组列
df_final = df_final.drop(['addresses', 'plans'], axis=1)

# 导出为CSV文件
df_final.to_csv('flattened_doctor_data.csv', index=False)

说明

这样处理后,每个地址会和每个计划组合成一行,确保所有关联关系都被保留。如果你的业务不需要这种笛卡尔积,而是希望把地址/计划作为列表保留,可以调整逻辑,但根据需求拆分为单独列的话,这种方式是最直接有效的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 11:36:06