用熊猫标准化嵌套的json数据

时间:2019-08-16 16:49:32

标签: python json pandas dataframe nested

我正在尝试使用嵌套的json,但未达到所需的结果。

我有这样的JSON数据:

{'from_cache': True,
 'results': [{'data': [{'date': '2019/06/01', 'value': 0},
                   {'date': '2019/06/02', 'value': 0},
                   {'date': '2019/08/09', 'value': 7087},
                   {'date': '2019/08/10', 'value': 0},
                   {'date': '2019/08/11', 'value': 15},
                   {'date': '2019/08/12', 'value': 14177},
                   {'date': '2019/08/13', 'value': 0}],
          'name': 'Clicks'},
     {'data': [{'date': '2019/06/01', 'value': 0.0},
                   {'date': '2019/06/02', 'value': 0.0},
                   {'date': '2019/06/03', 'value':1.0590561064390611},
                   {'date': '2019/08/11', 'value':1.8610421836228286},
                   {'date': '2019/08/12', 'value': 6.191613785151832},
                   {'date': '2019/08/13', 'value': 0.0}],
          'name': 'Rate'}]}

预期结果是这样的数据框:

date         Clicks   Rate
2019/06/01   0        0.0
2019/06/02   0        0.0
2019/08/09   7087     1.0590561064390611

如您所见,我希望每个“名称”都作为具有相应“值”的数据框列。

我正在使用pd.io.json_normalize,但没有成功获得此结果。我达到的最好结果是一个带有以下列的数据框:日期,值,名称。

有人可以帮我吗?

2 个答案:

答案 0 :(得分:2)

IIUC,使用pd.concataxis=1

df = pd.concat([pd.DataFrame(k['data']).rename(columns={'value': k['name']})\
                                       .set_index('date') 
                for k in d['results']], 
                sort=False, 
                axis=1)

             Clicks      Rate
2019/06/01      0.0  0.000000
2019/06/02      0.0  0.000000
2019/08/09   7087.0       NaN
2019/08/10      0.0       NaN
2019/08/11     15.0  1.861042
2019/08/12  14177.0  6.191614
2019/08/13      0.0  0.000000
2019/06/03      NaN  1.059056

使用pivot_table

的另一种方法
df = pd.concat([pd.DataFrame(x['data']).assign(column=x['name']) for x in d['results']])\
       .pivot_table(columns='column', index='date', values='value')

答案 1 :(得分:1)

无循环:

from pandas.io.json import json_normalize
import matplotlib.pyplot as plt

df = json_normalize(data['results'], record_path=['data'], meta=['name'])    
df.date = pd.to_datetime(df.date)

df_clicks = df[df.name == 'Clicks'].drop('name', axis=1).rename(columns={'value': 'Clicks'})
df_rate = df[df.name == 'Rate'].drop('name', axis=1).rename(columns={'value': 'Rate'})

df_final = df_clicks.merge(df_rate, how='outer', sort=True)
df_final.set_index('date', drop=True, inplace=True)

enter image description here

  • 意外数据:
    • 2019-06-03:没有点击的费率
    • 2019-08-09:点击次数,但没有发生率

绘制它:

df_final.plot(kind='bar', logy=True)
plt.show()

enter image description here

建议使用新的json格式:

data = {'from_cache': True,
        'results': [{'date': '2019/06/01', 'Clicks': 0, 'Rate': 0},
                    {'date': '2019/06/02', 'Clicks': 0, 'Rate': 0},
                    {'date': '2019/06/03', 'Clicks': 0, 'Rate': 1.0590561064390611},
                    {'date': '2019/08/09', 'Clicks': 7087, 'Rate': 0},
                    {'date': '2019/08/10', 'Clicks': 0, 'Rate': 0},
                    {'date': '2019/08/11', 'Clicks': 15, 'Rate': 1.8610421836228286},
                    {'date': '2019/08/12', 'Clicks': 14177, 'Rate': 6.191613785151832},
                    {'date': '2019/08/13', 'Clicks': 0, 'Rate': 0}]}