如何用json_normalize将API嵌套JSON完全转换为Pandas DataFrame?
解决嵌套JSON全量解析为Pandas DataFrame的问题
问题场景
使用pd.json_normalize解析API返回的嵌套JSON时,仅能解析一级结构,agent_info.instances仍为列表格式,需要将所有嵌套键值对拆分为单独列。
示例数据
API返回的JSON响应
{ "id": "123", "name": "test_service", "agent_info": { "version": "1.0.0", "instances": [ {"instance_id": "inst_001", "status": "running", "cpu_usage": 25}, {"instance_id": "inst_002", "status": "idle", "cpu_usage": 10} ] }, "created_at": "2024-05-20T10:00:00Z" }
当前代码及输出
import pandas as pd import json # 加载API响应数据 api_response = ''' { "id": "123", "name": "test_service", "agent_info": { "version": "1.0.0", "instances": [ {"instance_id": "inst_001", "status": "running", "cpu_usage": 25}, {"instance_id": "inst_002", "status": "idle", "cpu_usage": 10} ] }, "created_at": "2024-05-20T10:00:00Z" } ''' data = json.loads(api_response) # 当前解析代码 df = pd.json_normalize(data) print(df)
当前输出(agent_info.instances为列表):
id name agent_info.version agent_info.instances created_at 0 123 test_service 1.0.0 [{'instance_id': 'inst_001', 'status': 'running', 'c... 2024-05-20T10:00:00Z
解决方法
方法一:一步到位(利用json_normalize的record_path和meta参数)
直接指定要展开的嵌套列表路径,同时保留其他层级的字段:
df_full = pd.json_normalize( data, # 指定需要展开的嵌套列表路径 record_path=['agent_info', 'instances'], # 指定需要保留的其他字段(支持嵌套路径) meta=[ 'id', 'name', ['agent_info', 'version'], 'created_at' ] ) # 可选:重命名列名,移除嵌套分隔符 df_full.columns = df_full.columns.str.replace('.', '_') print(df_full)
输出结果(所有字段均为单独列):
instance_id status cpu_usage id name agent_info_version created_at 0 inst_001 running 25 123 test_service 1.0.0 2024-05-20T10:00:00Z 1 inst_002 idle 10 123 test_service 1.0.0 2024-05-20T10:00:00Z
方法二:分步处理(适合复杂嵌套场景)
先解析一级结构,再展开列表并解析嵌套字典:
# 1. 解析一级结构 df = pd.json_normalize(data) # 2. 展开agent_info.instances列表,每行对应一个实例 df_exploded = df.explode('agent_info.instances', ignore_index=True) # 3. 解析展开后的实例字典为单独列 df_instances = pd.json_normalize(df_exploded['agent_info.instances']) # 4. 合并原数据(移除原列表列)与实例列 df_full = pd.concat([df_exploded.drop('agent_info.instances', axis=1), df_instances], axis=1) # 可选:重命名列名 df_full.columns = df_full.columns.str.replace('.', '_') print(df_full)
该方法输出与方法一完全一致,适合嵌套层级更多、结构更复杂的场景。
注意事项
- 若
agent_info.instances可能为空列表,使用explode后会生成空行,可追加df_full = df_full.dropna()处理; - 若API返回的是多个顶层对象的列表(如
[{}, {}, ...]),上述两种方法同样适用,直接将列表传入pd.json_normalize即可; - 列名重命名为可选操作,可根据业务需求调整格式。
内容的提问来源于stack exchange,提问作者anuof90
相关产品推荐
相关产品推荐

