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

Pandas处理非固定结构嵌套JSON创建DataFrame问题咨询

pandas 不规则嵌套JSON拆分为多列方案

问题说明

  • 需将接口返回的JSON响应在pandas中拆分到不同列,直接使用pd.json_normalize无法正确拆分嵌套对象,多次尝试其他方案均未达到预期
  • 待处理JSON结构不固定,存在三类数据形态:
    • 包含financeInfo字段
    • 不包含financeInfo字段
    • 仅存在financeInfoAttributes字段、无financeInfo字段
  • 待处理JSON样例如下:
{
  "codeId": "fc-5599",
  "financeInfo": [
    {
      "date": "2022-01-30",
      "totalReturn": 0.022425456852
    },
    {
      "date": "2022-01-30",
      "totalReturn": 0.022425456852
    },
    {
      "date": "2022-01-30",
      "totalReturn": 0.022425456852
    },
    {
      "date": "2022-01-30",
      "totalReturn": 0.022425456852
    },
    {
      "date": "2022-01-30",
      "totalReturn": 0.022425456852
    }, 
    {
      "date": "2022-02-28",
       "totalReturn": -0.0424735070051586,
       "financeInfoAttributes": [
         {
           "attributeId": "a-256",
           "value": "12.032791372796499"
         },
         {
           "attributeId": "a-257",
           "value": "9.975964795996589"
         },
         {
           "attributeId": "a-258",
           "value": "4.719852927810759"
         },
         {
           "attributeId": "a-259",
           "value": "4.18144793134823"
         }     
      ]
    }
  ]
}
  • 原有实现采用多次pd.merge关联拆分后的表,核心代码如下:
normalizedfinanceInfo = pd.json_normalize(financeInfo[0], max_level=1)
financeInfoAndfinanceInfoAttributes = pd.merge(normalizedfinanceInfo , financeInfoAttributes, left_index=True, right_index=True, how='outer')
result = pd.merge(codeId, financeInfoAndfinanceInfoAttributes , left_index=True, right_index=True, how='left')
final_result = pd.DataFrame(result)

该方案流程冗余,且存在索引对齐错误、字段匹配异常问题,输出结果不符合预期。

实现方案

直接利用pd.json_normalize的路径配置参数处理两层嵌套结构,搭配空值自动忽略逻辑适配不固定的JSON结构,无需多次手动merge。

完整代码

import pandas as pd
import numpy as np

# raw_data 替换为接口返回的JSON解析结果(即response.json()返回值)
raw_data = {} # 此处替换为实际输入数据

# 前置判断:无financeInfo字段时直接生成仅含codeId的结果
if 'financeInfo' not in raw_data:
    final_result = pd.json_normalize(raw_data)
else:
    # 第一步:展开顶层字段与financeInfo数组,自动忽略不存在的字段
    df_finance = pd.json_normalize(
        raw_data,
        record_path='financeInfo',
        meta=['codeId'],
        errors='ignore'
    )

    # 第二步:处理financeInfo下嵌套的financeInfoAttributes数组
    if 'financeInfoAttributes' in df_finance.columns:
        # 展开属性数组,保留关联主键
        df_attr = pd.json_normalize(
            df_finance.to_dict('records'),
            record_path='financeInfoAttributes',
            meta=['codeId', 'date', 'totalReturn'],
            errors='ignore'
        )
        # 将属性键值对透视成独立列
        df_attr_pivot = df_attr.pivot(
            index=['codeId', 'date', 'totalReturn'],
            columns='attributeId',
            values='value'
        ).reset_index()
        # 合并属性列与财务主表,缺失值自动填充NaN
        final_result = df_finance.drop(columns=['financeInfoAttributes']).merge(
            df_attr_pivot,
            on=['codeId', 'date', 'totalReturn'],
            how='left'
        )
    else:
        final_result = df_finance

# 可选:将属性列转换为数值类型
attr_cols = [col for col in final_result.columns if str(col).startswith('a-')]
final_result[attr_cols] = final_result[attr_cols].astype(np.float64)

关键逻辑说明

  • errors='ignore'参数:自动跳过当前数据中不存在的字段,不会抛出KeyError,适配三类结构不固定的输入数据
  • 分层展开逻辑:分别对两层数组结构调用json_normalize,通过meta参数保留关联主键,避免索引错位
  • 透视转换:将长格式的属性键值对转换为宽表列,和财务数据行自动对齐
  • 边界适配:针对无financeInfo、无financeInfoAttributes的场景做了分支处理,不需要额外修改逻辑即可兼容所有输入形态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 02:24:33