Pandas json_normalize会产生令人困惑的`KeyError`消息?

时间:2015-08-29 22:48:02

标签: python json dictionary pandas

我正在尝试将嵌套的JSON转换为Pandas数据帧。我一直在使用json_normalize成功,直到遇到某个JSON。我已经制作了一个较小的版本来重现问题。

from pandas.io.json import json_normalize

json=[{"events": [{"schedule": {"date": "2015-08-27",
     "location": {"building": "BDC", "floor": 5},
     "ID": 815},
    "group": "A"},
   {"schedule": {"date": "2015-08-27",
     "location": {"building": "BDC", "floor": 5},
 "ID": 816},
"group": "A"}]}]
然后我跑了:

json_normalize(json[0],'events',[['schedule','date'],['schedule','location','building'],['schedule','location','floor']])

期待看到这样的事情:

ID      group   schedule.date   schedule.location.building schedule.location.floor  
'815'   'A'     '2015-08-27'            'BDC'                       5
'816'   'A'     '2015-08-27'            'BDC'                       5

但我得到了这个错误:

In [2]: json_normalize(json[0],'events',[['schedule','date'],['schedule','location','building'],['schedule','location','floor']])
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-2-b588a9e3ef1d> in <module>()
----> 1 json_normalize(json[0],'events',[['schedule','date'],['schedule','location','building'],['schedule','location','floor']])

/Users/logan/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/io/json.pyc in json_normalize(data, record_path, meta, meta_prefix, record_prefix)
    739                 records.extend(recs)
    740
--> 741     _recursive_extract(data, record_path, {}, level=0)
    742
    743     result = DataFrame(records)

/Users/logan/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/io/json.pyc in _recursive_extract(data, path, seen_meta, level)
    734                         meta_val = seen_meta[key]
    735                     else:
--> 736                         meta_val = _pull_field(obj, val[level:])
    737                     meta_vals[key].append(meta_val)
    738

/Users/logan/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/io/json.pyc in _pull_field(js, spec)
    674         if isinstance(spec, list):
    675             for field in spec:
--> 676                 result = result[field]
    677         else:
    678             result = result[spec]

KeyError: 'schedule'

3 个答案:

答案 0 :(得分:3)

在这种情况下,我认为你只是使用它:

In [57]: json_normalize(data[0]['events'])
Out[57]: 
  group  schedule.ID schedule.date schedule.location.building  \
0     A          815    2015-08-27                        BDC   
1     A          816    2015-08-27                        BDC   

   schedule.location.floor  
0                        5  
1                        5  

meta路径([['schedule','date']...])用于指定与记录处于同一嵌套级别的数据,即与“事件”处于同一级别。它看起来不像json_normalize处理嵌套列表的dicts特别好,所以如果你的实际数据要复杂得多,你可能需要做一些手工整形。

答案 1 :(得分:1)

当json的结构不一致时,我得到了KeyError。意思是,当json中缺少一个嵌套的结构时,我得到了KeyError。

https://pandas.pydata.org/pandas-docs/stable/generated/pandas.io.json.json_normalize.html

从pandas文档站点上提到的示例中,如果您在其中一条记录上缺少嵌套标记(县),则会出现KeyError。为避免这种情况,您可能必须确保忽略缺少的标记或仅考虑具有嵌套数据的嵌套列/标记的记录。

答案 2 :(得分:0)

我遇到了同样的问题!这个线程很有帮助,尤其是降落伞py的答案。

我使用以下方法找到了解决方案:

df.dropna(subset = *column(s) with nested data*)

然后将结果df保存为新的json。 加载新的json,现在您将能够展平嵌套列。

可能有一种更有效的解决方法,但是我的解决方案有效。

编辑:忘了提一下,我尝试在*errors = 'ignore'*中使用json.normalize()参数,但没有帮助。