我正在从返回JSON的API中读取 我正在使用
from pandas.io.json import json_normalize
flatten = json_normalize(data['results'])
要展平JSON,现在输出就像
breakdowns metric time value
0 [{u'key': u'platform', u'value': u'ios'}] fb_ad_network_imp 2018-08-29T07:00:00+0000 12
1 [{u'key': u'platform', u'value': u'android'}] fb_ad_network_imp 2018-08-29T07:00:00+0000 32
2 [{u'key': u'platform', u'value': u'ios'}] fb_ad_network_request 2018-08-29T07:00:00+0000 33
3 [{u'key': u'platform', u'value': u'android'}] fb_ad_network_request 2018-08-29T07:00:00+0000 132
现在我想根据平台将这4行压缩成2行,
platform date clicks impressions
0 ios 2018-08-29 33 12
1 android 2018-08-29 132 32
我还映射了以下名称:
fb_ad_network_request
-> clicks
fb_ad_network_imp
-> impressions
什么是最好的方法?
答案 0 :(得分:5)
将pivot_table
展平后,可以使用dict
dddd['platform']=pd.concat([pd.DataFrame(x) for x in dddd.breakdowns]).value.values
dddd.pivot_table(index=['platform','time'],columns='metric',values='value',aggfunc=sum).reset_index()
Out[237]:
metric platform time fb_ad_network_imp fb_ad_network_request
0 android 2018-08-29 32 132
1 ios 2018-08-29 12 33
答案 1 :(得分:2)
设置
tmp = pd.Series([i[0].get('value', None) for i in df.breakdowns]).rename('platform')
mapping = {
'columns': {
'fb_ad_network_request': 'clicks',
'fb_ad_network_imp': 'impressions',
'time': 'date',
}
}
groupby
和unstack
:(df.join(tmp).groupby(['platform', df.time.dt.date, 'metric'])
.value.sum().unstack().reset_index().rename(**mapping))
metric platform date impressions clicks
0 android 2018-08-29 32 132
1 ios 2018-08-29 12 33
答案 2 :(得分:2)
设置
df = pd.DataFrame({
'breakdowns': [[{u'key': u'platform', u'value': u'ios'}],
[{u'key': u'platform', u'value': u'android'}],
[{u'key': u'platform', u'value': u'ios'}],
[{u'key': u'platform', u'value': u'android'}]],
'metric': ['fb_ad_network_imp'] * 2 + ['fb_ad_network_request'] * 2,
'time': ['2018-08-29T07:00:00+0000'] * 4,
'value': [12, 32, 33, 132]
})
df['time'] = pd.DatetimeIndex(df['time'])
解决方案
这假设time
列具有时间戳,然后使用dt
访问器方法获取日期并将其分配给链式数据框中的新列。
我使用了lambda函数从细分列中获取平台,然后将这些值与日期和指标分组在一起。该指标已取消堆叠,因此每个指标都将位于单独的列中,重置索引并将列重命名为所需的格式。
result = (
df
.assign(date=df['time'].dt.date)
.groupby([df['breakdowns'].apply(lambda x: x[0].get('value')), 'date', 'metric'])
['value']
.sum()
.unstack('metric')
.reset_index()
.rename(columns={
'breakdowns': 'platform',
'fb_ad_network_request': 'clicks',
'fb_ad_network_imp': 'impressions'
})
)
result.columns.name = None
>>> result
platform date impressions clicks
0 android 2018-08-29 32 132
1 ios 2018-08-29 12 33
答案 3 :(得分:1)
通过字典组合创建pandas.Series
m0 = dict(fb_ad_network_imp='impressions', fb_ad_network_request='clicks')
flatten.time = pd.to_datetime(flatten.time).dt.floor('D')
s = pd.Series({
(b[0]['value'], t, m0[m]): v for b, m, t, v in flatten.values
})
s.rename_axis(['platform', 'date', None]).unstack().reset_index()
platform date clicks impressions
0 android 2018-08-29 132 32
1 ios 2018-08-29 33 12
类似地
m0 = dict(fb_ad_network_imp='impressions', fb_ad_network_request='clicks')
def f(tup):
b = tup.breakdowns[0]['value']
t = pd.to_datetime(tup.time).floor('D')
m = m0[tup.metric]
v = tup.value
return ((b, t, m), v)
s = pd.Series(dict(map(f, flatten.itertuples())))
s.rename_axis(['platform', 'date', None]).unstack().reset_index()
platform date clicks impressions
0 android 2018-08-29 132 32
1 ios 2018-08-29 33 12