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

如何用Python递归将JSON转为通用型合并表格?

通用型JSON转合并表格的Python实现问题

我正在用Python构建数据管道,现在卡在一个需求上——要递归把JSON响应转换成单个合并表格,而且得是通用脚本,不用指定JSON各部分名称就能适配其他JSON文件。我是编程新手,附上示例JSON、期望输出说明和当前代码,求解决方案。

示例JSON

{
    "area": {"id": 2072},
    "competition": {"id": 2021},
    "season": {"id": 733},
    "standings": [
        {
            "type": "TOTAL",
            "table": [
                {"position": 1, "team": {"id": 65, "name": "Manchester City FC"}, "playedGames": 37},
                {"position": 2, "team": {"id": 64, "name": "Liverpool FC"}, "playedGames": 36}
            ]
        },
        {
            "type": "HOME",
            "table": [
                {"position": 1, "team": {"id": 64, "name": "Liverpool FC"}, "playedGames": 18},
                {"position": 2, "team": {"id": 65, "name": "Manchester City FC"}, "playedGames": 18}
            ]
        }
    ]
}

期望输出

要生成一个包含以下列的表格:

  • area_id、competition_id、season_id、type、position、team_id、team_name、playedGames

对应的数据行:

  1. 2072 | 2021 | 733 | TOTAL | 1 | 65 | Manchester City FC | 37
  2. 2072 | 2021 | 733 | TOTAL | 2 | 64 | Liverpool FC | 36
  3. 2072 | 2021 | 733 | HOME | 1 | 64 | Liverpool FC | 18
  4. 2072 | 2021 | 733 | HOME | 2 | 65 | Manchester City FC | 18

当前代码

import pandas as pd

def flatten_json(json_data, prefix=''):
    flattened_data = {}
    for key, value in json_data.items():
        if isinstance(value, dict):
            flattened_data.update(flatten_json(value, prefix + key + '.'))
        elif isinstance(value, list):
            for i, item in enumerate(value):
                flattened_data.update(flatten_json(item, prefix + key + '.' + str(i) + '.'))
        else:
            flattened_data[prefix + key] = value
    return flattened_data

flattened_data = flatten_json(json_data)
df = pd.DataFrame([flattened_data])
df = df.rename(columns=lambda x: '.'.join(x.split('.')[-2:]) if '.' in x else x)
df = df[df.columns.dropna()]
print(df)

解决方案

你的原代码问题在于把所有列表元素都平铺成同一层级的键值对,最后只生成了一行数据,没法展开成我们需要的多行表格。核心思路其实是先抓顶层的公共字段,再逐层展开嵌套列表,把公共字段和每一条明细数据合并,这样就能生成通用的表格了。

修改后的代码如下:

import pandas as pd

def flatten_dict(d, parent_key='', sep='_'):
    # 把嵌套字典转成"父键_子键"的扁平格式,比如team.id变成team_id
    items = []
    for k, v in d.items():
        new_key = f"{parent_key}{sep}{k}" if parent_key else k
        if isinstance(v, dict):
            items.extend(flatten_dict(v, new_key, sep=sep).items())
        else:
            items.append((new_key, v))
    return dict(items)

def json_to_table(json_data):
    # 第一步:提取顶层的公共字段(不是列表的那些,比如area、competition)
    common_fields = {}
    list_fields = []
    for key, value in json_data.items():
        if isinstance(value, dict):
            common_fields.update(flatten_dict(value, key))
        elif isinstance(value, list):
            list_fields.append((key, value))
    
    # 第二步:逐层遍历嵌套列表,把公共字段和每条明细合并
    all_rows = []
    for field_name, field_data in list_fields:
        for item in field_data:
            # 先扁平化当前列表条目(比如取出type字段)
            flattened_item = flatten_dict(item)
            # 找到条目里的子列表(比如table)
            for sub_key, sub_list in flattened_item.items():
                if isinstance(sub_list, list):
                    # 遍历子列表里的每一条数据
                    for sub_item in sub_list:
                        # 扁平化子条目(比如把team字典转成team_id、team_name)
                        flattened_sub = flatten_dict(sub_item)
                        # 合并公共字段、当前条目非列表字段、子条目字段
                        row = {**common_fields}
                        # 添加当前条目的非列表字段(比如type)
                        for k, v in flattened_item.items():
                            if not isinstance(v, list):
                                row[k] = v
                        # 添加子条目字段
                        row.update(flattened_sub)
                        all_rows.append(row)
    
    return pd.DataFrame(all_rows)

# 示例JSON(修正了原JSON的语法错误)
json_data = {
    "area": {"id": 2072},
    "competition": {"id": 2021},
    "season": {"id": 733},
    "standings": [
        {
            "type": "TOTAL",
            "table": [
                {"position": 1, "team": {"id": 65, "name": "Manchester City FC"}, "playedGames": 37},
                {"position": 2, "team": {"id": 64, "name": "Liverpool FC"}, "playedGames": 36}
            ]
        },
        {
            "type": "HOME",
            "table": [
                {"position": 1, "team": {"id": 64, "name": "Liverpool FC"}, "playedGames": 18},
                {"position": 2, "team": {"id": 65, "name": "Manchester City FC"}, "playedGames": 18}
            ]
        }
    ]
}

df = json_to_table(json_data)
print(df)

代码说明

  • flatten_dict:专门处理嵌套字典,把多层结构转成扁平的键值对,方便后续合并
  • json_to_table:
    • 先把顶层的非列表字段(比如area、competition)提取出来作为所有行的公共数据
    • 然后逐层遍历JSON里的列表,把每个列表条目里的非列表字段(比如type)和子列表的明细数据(比如table里的球队信息),再加上公共字段,拼成一行完整数据
    • 最后把所有行收集起来生成DataFrame

运行结果

执行后会输出符合期望的表格:

area_id  competition_id  season_id   type  position  team_id          team_name  playedGames
0     2072            2021        733  TOTAL         1       65  Manchester City FC           37
1     2072            2021        733  TOTAL         2       64     Liverpool FC           36
2     2072            2021        733   HOME         1       64     Liverpool FC           18
3     2072            2021        733   HOME         2       65  Manchester City FC           18

内容的提问来源于stack exchange,提问作者Geert Van Der Weide

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 05:45:06