复杂JSON转Pandas DataFrame报错修复及字典可视化调试方法
报错原因
你调用的OECD接口返回的是高度嵌套的SDMX-JSON结构,包含元数据、维度定义、观测值等多个层级,pd.read_json默认会尝试将JSON顶层键直接映射为DataFrame的列,但这些顶层键对应的取值类型不统一,部分是嵌套字典、部分是数组、部分是标量,pandas无法自动对齐结构、确定列的排序逻辑,因此触发Mixing dicts with non-Series may lead to ambiguous ordering报错。
修复方案
不要直接用pd.read_json解析嵌套结构,先将JSON加载为Python字典,再手动提取需要的业务字段转换为DataFrame,示例代码如下:
import pandas as pd import requests import json # 拉取原始数据并转换为字典 url = 'https://stats.oecd.org/sdmx-json/data/QNA/AUS+AUT.GDP+B1_GE.CUR+VOBARSA.Q/all?startTime=2009-Q2&endTime=2011-Q4' resp = requests.get(url, verify=True) raw_data = resp.json() # 提取维度映射关系 country_map = {str(i): v['name'] for i, v in enumerate(raw_data['structure']['dimensions']['series'][0]['values'])} indicator_map = {str(i): v['name'] for i, v in enumerate(raw_data['structure']['dimensions']['series'][1]['values'])} unit_map = {str(i): v['name'] for i, v in enumerate(raw_data['structure']['dimensions']['series'][2]['values'])} freq_map = {str(i): v['name'] for i, v in enumerate(raw_data['structure']['dimensions']['series'][3]['values'])} time_map = {str(i): v['name'] for i, v in enumerate(raw_data['structure']['dimensions']['observation'][0]['values'])} # 提取观测值并转换为结构化列表 series_data = raw_data['dataSets'][0]['series'] records = [] for series_key, series_val in series_data.items(): dims = series_key.split(':') country = country_map[dims[0]] indicator = indicator_map[dims[1]] unit = unit_map[dims[2]] freq = freq_map[dims[3]] for obs_key, obs_val in series_val['observations'].items(): time = time_map[obs_key] value = obs_val[0] records.append({ '国家': country, '指标': indicator, '单位': unit, '频率': freq, '时间': time, '数值': value }) # 生成最终DataFrame df = pd.DataFrame(records)
如果需要频繁处理SDMX格式数据,也可以安装sdmx1库直接解析,无需手动处理嵌套结构。
嵌套字典可视化调试方法
可以通过以下几种方式快速查看嵌套字典的结构,辅助调试:
- 格式化打印:通过
json.dumps的indent参数输出带缩进的结构化内容,支持指定最大层级避免内容过多
# 打印完整结构,缩进为2个空格 print(json.dumps(raw_data, indent=2, ensure_ascii=False)) # 只打印前3层结构,避免内容溢出 def print_dict(d, depth=0, max_depth=3): if depth > max_depth: return for k, v in d.items(): print(' '*depth + str(k)) if isinstance(v, dict): print_dict(v, depth+1, max_depth) print_dict(raw_data)
- 简洁打印:用pprint模块指定打印深度,快速查看顶层结构
import pprint pprint.pprint(raw_data, depth=2)
- 交互式可视化:如果使用Jupyter环境,安装JSON预览插件后,直接调用
display(raw_data)即可得到可折叠、可搜索的交互式字典结构,方便逐层查看嵌套内容。
内容的提问来源于stack exchange,提问作者nutix
相关产品推荐
相关产品推荐

