Python:Json解压缩到数据帧

时间:2018-02-04 10:15:35

标签: python json pandas dataframe

我正在尝试解析json我已经从api收到了一个pandas DataFrame。那个json是ierarchical,在这个例子中我有这个行的城市代码,行名和站点列表。不幸的是我不能“打开”它。非常感谢您的帮助和解释。

JSON:

{'id': '1',
 'lines': [{'hex_color': 'FFCD1C',
   'id': '8',
   'name': 'Калининская',          <------Line name
   'stations': [{'id': '8.189',
     'lat': 55.745113,
     'lng': 37.864052,
     'name': 'Новокосино',         <------Station 1   
     'order': 0},
    {'id': '8.88',
     'lat': 55.752237,
     'lng': 37.814587,
     'name': 'Новогиреево',        <------Station 2
     'order': 1},
etc.

我正在尝试从最低级别接收evrything并添加所有更高级别的信息(从linename开始):

c = r.content
j = simplejson.loads(c)

tmp=[]
i=0
data1=pd.DataFrame(tmp)
data2=pd.DataFrame(tmp)

pd.concat
station['name']

for station in j['lines']:

    data2 = data2.append(pd.DataFrame(station['stations'], station['name']),ignore_index=True)
data2

再一次 - 问题是: 如何使它工作? 这个解决方案是最佳解决方案,还是我应该了解一些功能?

更新 Json正常解析:

json_normalize(j)

id  lines                                              name
1   [{'hex_color': 'FFCD1C', 'stations': [{'lat': ...   Москва

我可以得到当前的DataFrame:

data2 = data2.append(pd.DataFrame(station['stations']),ignore_index=True)
    id      lat         lng         name        order
0   8.189   55.745113   37.864052   Новокосино  0
1   8.88    55.752237   37.814587   Новогиреево 1

所需的数据帧可表示为:

id  lat     lng                     name            order  Line_Name    Id_Top Name_Top
0   8.189   55.745113   37.864052   Новокосино      0      Калининская  1       Москва 
1   8.88    55.752237   37.814587   Новогиреево     1      Калининская  1       Москва

2 个答案:

答案 0 :(得分:1)

除了MaxU的回答之外,我认为你仍然需要最高等级id,这应该有效:

json_normalize(data, ['lines','stations'], ['id',['lines','name']],record_prefix='station_')

答案 1 :(得分:0)

假设您有以下词典:

In [70]: data
Out[70]:
{'id': '1',
 'lines': [{'hex_color': 'FFCD1C',
   'id': '8',
   'name': 'Калининская',
   'stations': [{'id': '8.189',
     'lat': 55.745113,
     'lng': 37.864052,
     'name': 'Новокосино',
     'order': 0},
    {'id': '8.88',
     'lat': 55.752237,
     'lng': 37.814587,
     'name': 'Новогиреево',
     'order': 1}]}]}

解决方案:使用pandas.io.json.json_normalize

In [71]: pd.io.json.json_normalize(data['lines'],
                                   ['stations'],
                                   ['name', 'id'],
                                   meta_prefix='parent_')
Out[71]:
      id        lat        lng         name  order  parent_name parent_id
0  8.189  55.745113  37.864052   Новокосино      0  Калининская         8
1   8.88  55.752237  37.814587  Новогиреево      1  Калининская         8

更新:反映更新后的问题

res = (pd.io.json.json_normalize(data,
                                 ['lines', 'stations'],
                                 ['id', ['lines', 'name']],
                                 meta_prefix='Line_')
         .assign(Name_Top='Москва'))

结果:

In [94]: res
Out[94]:
      id        lat        lng         name  order Line_id Line_lines.name Name_Top
0  8.189  55.745113  37.864052   Новокосино      0       1     Калининская   Москва
1   8.88  55.752237  37.814587  Новогиреево      1       1     Калининская   Москва