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

如何动态将任意嵌套JSON转换为CSV或DataFrame且列表按行展开

嵌套JSON转按行展开DataFrame解决方案

以下代码可实现任意嵌套JSON结构转换为DataFrame,自动将列表按行展开,非列表公共字段复制到每一行,嵌套层级用.作为列名分隔符:

import pandas as pd
from pandas import json_normalize

def nested_json_to_df(data, sep='.'):
    # 扁平化非列表字段,同时识别所有列表类型字段
    def flatten_helper(x, parent_key=''):
        base_fields = {}
        list_fields = {}
        if isinstance(x, dict):
            for k, v in x.items():
                current_key = f"{parent_key}{sep}{k}" if parent_key else k
                if isinstance(v, list):
                    list_fields[current_key] = v
                elif isinstance(v, dict):
                    sub_base, sub_list = flatten_helper(v, current_key)
                    base_fields.update(sub_base)
                    list_fields.update(sub_list)
                else:
                    base_fields[current_key] = v
        return base_fields, list_fields

    # 处理根节点为列表的场景
    if isinstance(data, list):
        result_dfs = []
        for item in data:
            base, lists = flatten_helper(item)
            if not lists:
                result_dfs.append(pd.DataFrame([base]))
                continue
            # 取第一个识别到的列表按行展开,多列表场景可自行调整优先级逻辑
            list_key, list_val = next(iter(lists.items()))
            base_df = pd.DataFrame([base]*len(list_val))
            list_df = json_normalize(list_val, sep=sep).add_prefix(f"{list_key}{sep}")
            result_dfs.append(pd.concat([base_df.reset_index(drop=True), list_df.reset_index(drop=True)], axis=1))
        return pd.concat(result_dfs, ignore_index=True)
    else:
        base, lists = flatten_helper(data)
        if not lists:
            return pd.DataFrame([base])
        list_key, list_val = next(iter(lists.items()))
        base_df = pd.DataFrame([base]*len(list_val))
        list_df = json_normalize(list_val, sep=sep).add_prefix(f"{list_key}{sep}")
        return pd.concat([base_df.reset_index(drop=True), list_df.reset_index(drop=True)], axis=1)

使用示例

测试输入1

input1 = {"menu": {
    "header": "SVG Viewer",
    "items": [
        {"id": "Open"},
        {"id": "OpenNew", "label": "Open New"},
        None,
        {"id": "ZoomIn", "label": "Zoom In"},
        {"id": "ZoomOut", "label": "Zoom Out"},
        {"id": "OriginalView", "label": "Original View"},
        None,
        {"id": "Quality"},
        {"id": "Pause"},
        {"id": "Mute"},
        None,
        {"id": "Find", "label": "Find..."},
        {"id": "FindAgain", "label": "Find Again"},
        {"id": "Copy"},
        {"id": "CopyAgain", "label": "Copy Again"},
        {"id": "CopySVG", "label": "Copy SVG"},
        {"id": "ViewSVG", "label": "View SVG"},
        {"id": "ViewSource", "label": "View Source"},
        {"id": "SaveAs", "label": "Save As"},
        None,
        {"id": "Help"},
        {"id": "About", "label": "About Adobe CVG Viewer..."}
    ]
}}
df1 = nested_json_to_df(input1)
# 导出为CSV执行:df1.to_csv("output1.csv", index=False, encoding="utf-8-sig")

输出会保留menu.header公共列,menu.items的每个元素对应一行,每个元素的属性拆分为menu.items.id、menu.items.label列。

测试输入2

input2 = {"menu": {
  "id": "file",
  "value": "File",
  "popup": {
    "menuitem": [
      {"value": "New", "onclick": "CreateNewDoc()"},
      {"value": "Open", "onclick": "OpenDoc()"},
      {"value": "Close", "onclick": "CloseDoc()"}
    ]
  }
}}
df2 = nested_json_to_df(input2)

输出会保留menu.id、menu.value公共列,menu.popup.menuitem的每个元素对应一行,属性拆分为对应子列。

说明

  • 空的列表元素会自动填充空值到对应列
  • 支持根节点为列表的JSON结构转换
  • 存在多个并列列表时,默认展开第一个识别到的列表,可根据业务需求调整列表选择逻辑
  • 导出CSV可直接调用pandas自带的to_csv方法,编码建议用utf-8-sig避免中文乱码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 18:54:01