如何使用Pandas规范化JSON文件?解决TypeError报错问题
JSON转Pandas DataFrame报错修复
原始JSON数据
{"data": {"success":true, "timeseries":true, "start_date":"2022-10-01", "end_date":"2022-10-04", "base":"EUR", "rates": {"2022-10-01":{"NG":0.1448939471560284}, "2022-10-02":{"NG":0.14487923291390148}, "2022-10-03":{"NG":0.1454857922753868}, "2022-10-04":{"NG":0.1507352356663182}}, "unit":"per MMBtu"}}
报错代码
import pandas as pd import json with open(r'C:\Users\Gio\Desktop\tools\python\acrodata.json','r') as f: data = json.loads(f.read()) df_flatten = pd.json_normalize(data, record_path =['data']['rates'], meta=['success', 'timeseries', 'start_date','end_date','base']) print(df_flatten)
错误信息
TypeError: list indices must be integers or slices, not str
问题分析
record_path参数用法错误:它需要传入字符串组成的列表表示嵌套路径(比如['data', 'rates']),但你直接用['data']['rates']相当于先取列表第一个元素'data',再用'rates'索引字符串,自然触发类型错误。rates是字典结构(日期为键),而非数组,json_normalize默认处理数组型嵌套数据,直接传入字典无法解析。
修复方案
方法一:拆分处理(直观易读)
先将rates转成DataFrame,再把其他元数据合并进去:
import pandas as pd import json with open(r'C:\Users\Gio\Desktop\tools\python\acrodata.json','r') as f: data = json.loads(f.read()) # 提取rates字典,转成DataFrame并重置索引 rates_df = pd.DataFrame.from_dict(data['data']['rates'], orient='index').reset_index() rates_df.rename(columns={'index': 'date'}, inplace=True) # 提取元数据并批量添加到DataFrame中 meta_data = data['data'] for col in ['success', 'timeseries', 'start_date', 'end_date', 'base', 'unit']: rates_df[col] = meta_data[col] print(rates_df)
方法二:适配json_normalize用法
把rates字典转换为列表格式,符合json_normalize的输入要求:
import pandas as pd import json with open(r'C:\Users\Gio\Desktop\tools\python\acrodata.json','r') as f: data = json.loads(f.read()) # 将rates字典转为包含日期和NG值的列表 rates_list = [{'date': date, **value} for date, value in data['data']['rates'].items()] # 使用json_normalize处理,同时关联元数据 df_flatten = pd.json_normalize( rates_list, meta=[['data', 'success'], ['data', 'timeseries'], ['data', 'start_date'], ['data', 'end_date'], ['data', 'base'], ['data', 'unit']], data=data ) # 可选:重命名元数据列,去掉前缀 df_flatten.columns = df_flatten.columns.str.replace('data.', '') print(df_flatten)
两种方法最终都会得到如下结构的DataFrame:
| date | NG | success | timeseries | start_date | end_date | base | unit |
|---|---|---|---|---|---|---|---|
| 2022-10-01 | 0.144894 | True | True | 2022-10-01 | 2022-10-04 | EUR | per MMBtu |
| 2022-10-02 | 0.144879 | True | True | 2022-10-01 | 2022-10-04 | EUR | per MMBtu |
| 2022-10-03 | 0.145486 | True | True | 2022-10-01 | 2022-10-04 | EUR | per MMBtu |
| 2022-10-04 | 0.150735 | True | True | 2022-10-01 | 2022-10-04 | EUR | per MMBtu |
内容的提问来源于stack exchange,提问作者Premier12
相关产品推荐
相关产品推荐

