如何用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
对应的数据行:
- 2072 | 2021 | 733 | TOTAL | 1 | 65 | Manchester City FC | 37
- 2072 | 2021 | 733 | TOTAL | 2 | 64 | Liverpool FC | 36
- 2072 | 2021 | 733 | HOME | 1 | 64 | Liverpool FC | 18
- 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
相关产品推荐
相关产品推荐

