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

如何使用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

问题分析

  1. record_path参数用法错误:它需要传入字符串组成的列表表示嵌套路径(比如['data', 'rates']),但你直接用['data']['rates']相当于先取列表第一个元素'data',再用'rates'索引字符串,自然触发类型错误。
  2. 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:

dateNGsuccesstimeseriesstart_dateend_datebaseunit
2022-10-010.144894TrueTrue2022-10-012022-10-04EURper MMBtu
2022-10-020.144879TrueTrue2022-10-012022-10-04EURper MMBtu
2022-10-030.145486TrueTrue2022-10-012022-10-04EURper MMBtu
2022-10-040.150735TrueTrue2022-10-012022-10-04EURper MMBtu

内容的提问来源于stack exchange,提问作者Premier12

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 09:50:26