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

pandas json_normalize展平嵌套字典时record_path报KeyError

pandas展平嵌套JSON报KeyError: 'facilities'排查与解决

问题场景

处理AGSI公共API返回的JSON数据,目标是将嵌套的存储设施数据展平为单设施单行的结构化表,公司维度属性作为元数据附加到对应行。原有可正常运行的pd.json_normalize代码近日抛出键不存在错误,已人工确认业务数据中均存在facilities字段,无法定位问题。

待处理JSON结构(节选)

json = {'Austria': [{'image': 'iVBORw0KxuOmB00wGjmw4Y3XTA=',
   'short_name': 'astora',
   'name': 'astora GmbH',
   'url': 'http://www.astora.de',
   'eic': '21X000000001160J',
   'facilities': [{'eic': '21W000000000078N',
     'name': 'UGS Haidach (astora)',
     'country': {'code': 'AT', 'name': 'Austria'},
     'type': 'Storage Facility'}],
   'data': {'type': 'SSO',
    'country': {'code': 'AT', 'name': 'Austria'},
    'code': 'EU',
    'name': 'Europe'}},
  # 其余奥地利公司条目省略
]} 

原有实现代码

Austria = pd.json_normalize(json, record_path="facilities", meta=["name", "type", "eic"], meta_prefix='company_').drop(["url"], axis=1)

报错信息

KeyError: "Key 'facilities' not found. If specifying a record_path, all elements of data should have the path."

问题根源

报错核心原因是传入json_normalize的数据层级错误:

  • 该JSON顶层是国家名到公司列表的映射字典,facilities字段存在于每个公司条目中,不存在于顶层字典的键中
  • 之前代码可运行是因为传入的是json['Austria'](公司列表层级),本次运行直接传入了整个顶层字典,pandas遍历顶层键(国家名字符串)查找facilities字段,自然触发键不存在错误
  • 人工校验字段时检查的是公司列表内的条目,和pandas实际遍历的对象不一致,因此没发现问题

额外原有代码隐患:meta参数中传入的type字段不属于公司层级属性,公司条目下无该字段,修正入参后也会触发键错误,type实际存在于facilities子项和data嵌套结构中。

修复方案

单国家数据处理

明确传入对应国家的公司列表层级,同时修正meta参数为公司层级实际存在的字段,嵌套字段用列表形式声明路径:

import pandas as pd

Austria = pd.json_normalize(
    json["Austria"],  # 传入公司列表,而非整个顶层JSON
    record_path="facilities",
    meta=[
        "name",
        "short_name",
        "eic",
        "url",
        ["data", "type"],
        ["data", "code"]
    ],
    meta_prefix="company_"
)

全国家批量处理

先遍历顶层字典汇总所有国家的公司条目,再统一展平,可额外保留国家名称字段避免信息丢失:

all_companies = []
for country_name, company_list in json.items():
    for company in company_list:
        company["belong_country"] = country_name
        all_companies.append(company)

full_df = pd.json_normalize(
    all_companies,
    record_path="facilities",
    meta=[
        "name",
        "short_name",
        "eic",
        "url",
        "belong_country",
        ["data", "type"],
        ["data", "code"]
    ],
    meta_prefix="company_"
)

异常定位校验脚本

如果修正入参后仍报字段缺失错误,可运行以下脚本快速定位异常条目:

# 以奥地利数据为例
for idx, company in enumerate(json["Austria"]):
    if "facilities" not in company:
        print(f"索引{idx}的公司缺失facilities字段,公司名:{company.get('name', '未知')}")
    if not isinstance(company.get("facilities"), list):
        print(f"索引{idx}的公司facilities字段格式不是列表,公司名:{company.get('name', '未知')}")

内容的提问来源于stack exchange,提问作者el-don-quijote

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 07:54:33