Python 当试图提取某些属性时,json_normalize会产生一个KeyError

Python 当试图提取某些属性时,json_normalize会产生一个KeyError,python,json,pandas,json-normalize,Python,Json,Pandas,Json Normalize,以下是我的json文件的子集: d = {'data': {'questions': [{'id': 6574, 'text': 'Question #1', 'instructionalText': '', 'minimumResponses': 0, 'maxim

以下是我的json文件的子集:

d = {'data': {'questions': [{'id': 6574,
                             'text': 'Question #1',
                             'instructionalText': '',
                             'minimumResponses': 0,
                             'maximumResponses': None,
                             'sortOrder': 1,
                             'answers': [{'id': 362949, 'text': 'Answer #1', 'parentId': None},
                                         {'id': 362950, 'text': 'Answer #2', 'parentId': None},
                                         {'id': 362951, 'text': 'Answer #3', 'parentId': None},
                                         {'id': 362952, 'text': 'Answer #4', 'parentId': None}]}]}}

我想把它放在一个数据框中,每个问题都有一行,每个答案都有一行

Python代码:

from pandas import json_normalize
import json

fields = ['text','answers.text']

with open(R'response.json') as f:
    d = json.load(f)

data = json_normalize(d['data'],['questions'],errors='ignore')
data = data[fields]

print(data)
这会产生一个键错误:

KeyError: "['answers.text'] not in index"

我已经在这里呆了几个小时了,但完全无法理解这一点。我觉得它应该很简单,但从来都不是。

这是我通常使用的技术

  • json\u normalize()
    顶级列表
  • explode()
    child
    list
    reset_index()
    步骤3
  • apply(pd.Series)
  • 身份证件 文本 说明性文本 最小响应 最大响应 排序器 身份证 文本 父ID 0 6574 问题#1 0 1. 362949 答案#1 1. 6574 问题#1 0 1. 362950 答复#2 2. 6574 问题#1 0 1. 362951 答案#3 3. 6574 问题#1 0 1. 362952 答案#4
    • 使用
      record\u前缀
      ,使用
      record\u路径
      meta
      ,这样
      d
      可以一次全部规范化
      • 如果
        记录路径
        之间存在重叠的
        名称,并且
        'id'
        'text'
        都在这两个路径中,则将导致
        值错误
      • ValueError:元数据名称id冲突,需要区分前缀
        时未使用
        记录路径
    • 出现
      键错误
      是因为
      'answers.text'
      不在
      d
      中,它是由
      .json\u normalize()创建的
    • 如果有任何顶级
      df
      中不需要,请将其从
      meta
      中删除
    将熊猫作为pd导入
    #标准化
    df=pd.json_规范化(data=d['data']['questions'],
    记录路径=['answers'],
    meta=['id'、'text'、'instructionalText'、'minimumResponses'、'maximumResponses'、'sortOrder'],
    记录(前缀=“答案”)
    #显示(df)
    答案\u id答案\u文本答案\u家长id文本说明文本最小响应最大响应排序器
    0 362949回答#1无6574问题#1 0无1
    1362950回答#2无6574问题#10无1
    2 362951回答#3无6574问题#10无1
    3 362952回答#4无6574问题#10无1
    4 262949回答#1无4756问题#2无作弊,作弊者0无1
    5 262950回答#2无4756问题#2无作弊,作弊者0无1
    6 262951回答#3无4756问题#2无作弊,作弊者0无1
    7 262952回答#4无4756问题#2无作弊,作弊者0无1
    
    扩展测试数据
    d={'data':{'questions':[{'id]:6574,
    "文本":"问题#1",,
    “指令文本”:“,
    “最小响应”:0,
    “最大响应”:无,
    “巫师”:1,
    “answers”:[{'id':362949,'text':'Answer#1','parentId':None},
    {'id':362950,'text':'Answer#2','parentId':None},
    {'id':362951,'text':'Answer#3','parentId':None},
    {'id':362952,'text':'Answer#4','parentId':None}]},
    {'id':4756,
    "文本":"问题#2",,
    “说明文字”:“禁止作弊,作弊者”,
    “最小响应”:0,
    “最大响应”:无,
    “巫师”:1,
    “answers”:[{'id':262949,'text':'Answer#1','parentId':None},
    {'id':262950,'text':'Answer#2','parentId':None},
    {'id':262951,'text':'Answer#3','parentId':None},
    {'id':262952,'text':'Answer#4','parentId':None}]}
    

    • 至于另一个,不建议使用
      .apply(pd.Series)
      ,因为它速度非常慢。
      • 看到了吗
      • 10米行53分钟
    d = {'data': {'questions': [{'id': 6574,
        'text': 'Question #1',
        'instructionalText': '',
        'minimumResponses': 0,
        'maximumResponses': None,
        'sortOrder': 1,
        'answers': [{'id': 362949, 'text': 'Answer #1', 'parentId': None},
         {'id': 362950, 'text': 'Answer #2', 'parentId': None},
         {'id': 362951, 'text': 'Answer #3', 'parentId': None},
         {'id': 362952, 'text': 'Answer #4', 'parentId': None}]}]}}
    
    df = pd.json_normalize(d["data"]["questions"]).explode("answers").reset_index(drop=True)
    df = df.join(df["answers"].apply(pd.Series), rsuffix="_ans").drop(columns="answers")