读取pandas数据框中的嵌套json列表

时间:2018-11-29 10:50:09

标签: python json pandas

我有一个用以下代码读取的json文件。

import json
from pprint import pprint

with open('file.json') as json_data:
    d = json.load(json_data)
    json_data.close()
    pprint(d)

这给出了以下列表(不是字典):

[{'heading': 120.078125,
  'latitude': 60.84809244149443,
  'longitude': 12.706842578952859,
  'warning': None},
 {'heading': 178.2421875,
  'latitude': 60.847404287244046,
  'longitude': 12.70678398944969,
  'warning': {'disabled': True,
              'latitude': 60.8464254391783,
              'longitude': 12.70724018571071,
              'signal': [{'latitude': 52.388542281214,
                         'longitude': 4.6362899175721},
                        {'latitude': 52.388602884476,
                         'longitude': 4.6350475833697}]

             }}]

我发现的问题是嵌套的Json“警告” 当我使用以下代码拼合JSON

from pandas.io.json import json_normalize    
df = json_normalize(d)

我在列信号中得到一个带有JSON的数据框。 当我使用以下代码(而不是之前的代码)来展平JSON

df = json_normalize(d,"warning")

我收到以下错误

string indices must be integers

有人可以帮助我获取不带JSON的数据框吗? 预先感谢!

1 个答案:

答案 0 :(得分:0)

您的新json基本上是词典列表,其中某些词典可能包含另一个包含词典列表的字典。由于没有任何结构,json_normalize并不是可行的方法(请注意,json_normalize是针对半结构化json的文档,例如,不允许使用{{3}}记录存在于一个字典中,但不存在于另一个字典中。

因此,在将json读入pandas之前,您必须对其进行一些手动重塑。一种想法可能是整件事:

def flatten_json(y):
    #  As seen here: https://towardsdatascience.com/flattening-json-objects-in-python-f5343c794b10
    out = {}

    def flatten(x, name=''):
        if type(x) is dict:
            for a in x:
                flatten(x[a], name + a + '_')
        elif type(x) is list:
            i = 0
            for a in x:
                flatten(a, name + str(i) + '_')
                i += 1
        else:
            out[name[:-1]] = x

    flatten(y)
    return out

df = json_normalize([flatten_json(row) for row in d])
print(df)

      heading   latitude  longitude warning_disabled  warning_latitude  \
0  120.078125  60.848092  12.706843              NaN               NaN   
1  178.242188  60.847404  12.706784             True         60.846425   

   warning_longitude  warning_signal_0_latitude  warning_signal_0_longitude  \
0                NaN                        NaN                         NaN   
1           12.70724                  52.388542                     4.63629   

   warning_signal_1_latitude  warning_signal_1_longitude  
0                        NaN                         NaN  
1                  52.388603                    4.635048