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

如何不使用pandas将嵌套JSON转换为结构正确的有序列

嵌套JSON扁平化处理问题

问题描述

处理嵌套JSON结构做扁平化转表格时,原有对象遍历结合pandas生成DataFrame的方案输出结构不符合预期,尝试脱离pandas直接生成固定有序列的方案未得到目标结果,需要可落地的代码优化思路。

测试样例数据

{
  "financeCodeId": "fc-5599",
  "financeData": [
    {
      "date": "2022-01-30",
      "calcTotalReturn": 0.022425456852
    },
    {
      "date": "2022-01-30",
      "calcTotalReturn": 0.022425456852
    },
    {
      "date": "2022-01-30",
      "calcTotalReturn": 0.022425456852
    },
    {
      "date": "2022-01-30",
      "calcTotalReturn": 0.022425456852
    },
    {
      "date": "2022-01-30",
      "calcTotalReturn": 0.022425456852
    }, 
    {
      "date": "2022-02-28",
       "calcTotalReturn": -0.0424735070051586,
       "financeDataAttributes": [
       {
         "attributeId": "a-256",
         "value": "12.032791372796499"
       },
       {
       "attributeId": "a-257",
       "value": "9.975964795996589"
       },
       {
       "attributeId": "a-258",
       "value": "4.719852927810759"
       },
       {
       "attributeId": "a-259",
       "value": "4.18144793134823"
       }     
    ]
    }
  ]
}

注:原样例JSON存在括号缺失的语法问题,已补全修正。

原有问题代码

items = []
for i in response_finance['results']:
    items.append(i.get('financeCodeId'))
    for j in i['financeData']:
        if 'financeDataAttributes' not in j:
            items.append({j.get('date'), j.get('calcTotalReturn')})
        else:
            for k in j['financeDataAttributes']:
                items.append({k.get('attributeId'), k.get('value')})
df = pd.DataFrame.from_records(items)
flat = pd.json_normalize(json.loads(df.to_json(orient="records")))

效果对比

  • 实际错误输出:
    实际错误输出结构
  • 预期正确输出:
    预期输出结构

优化方案

原有代码问题

  1. 存入items列表的数据类型混杂,同时包含字符串、集合两种结构,pandas解析时无法对齐字段,直接导致列错位。
  2. 没有做层级关联:外层financeCodeId、中层日期/收益率、内层属性值被拆成了独立条目,没有按行绑定归属关系。
  3. 存在冗余逻辑:生成DataFrame后再转JSON再做json_normalize,多余的序列化/反序列化步骤容易引入格式问题。

修正后代码

核心思路是按行构造完整记录,每一行从最外层字段开始逐层绑定所有关联字段,动态属性直接展开为列名,最后一次性转DataFrame自动对齐列:

import pandas as pd

rows = []
for res_item in response_finance['results']:
    # 取最外层公共字段
    base_info = {"financeCodeId": res_item.get("financeCodeId")}
    # 遍历中层financeData条目
    for finance_item in res_item["financeData"]:
        current_row = base_info.copy()
        current_row["date"] = finance_item.get("date")
        current_row["calcTotalReturn"] = finance_item.get("calcTotalReturn")
        # 无属性的条目直接存入
        if "financeDataAttributes" not in finance_item:
            rows.append(current_row)
            continue
        # 有属性的条目,把每个attributeId作为列名,对应value作为列值
        for attr in finance_item["financeDataAttributes"]:
            current_row[attr.get("attributeId")] = attr.get("value")
        rows.append(current_row)

# 生成最终DataFrame,缺失字段自动填充空值
df = pd.DataFrame(rows)

# 如果需要固定列顺序,手动指定列序列即可
# df = df[["financeCodeId", "date", "calcTotalReturn", "a-256", "a-257", "a-258", "a-259"]]

如果需要完全不依赖pandas生成有序列结构,只需要先遍历全量数据收集所有出现过的attributeId作为固定列头,再按相同的行构造逻辑逐行写入即可,核心关联逻辑和上述代码一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 12:06:18