我有一个使用pivot_table方法从另一个pandas数据框(按商店销售)创建的数据透视pandas数据框(按地区销售)。
举个例子:
df = pd.DataFrame(
{'store':['A','B','C','D','E']*7,
'region':['NW','NW','SW','NE','NE']*7,
'date':['2017-03-30']*5+['2017-04-05']*5+['2017-04-07']*5+['2017-04-12']*5+['2017-04-13']*5+['2017-04-17']*5+['2017-04-20']*5,
'sales':[30,1,133,9,1,30,3,135,9,11,30,1,140,15,15,25,10,137,9,3,29,10,137,9,11,30,19,145,20,10,30,8,141,25,25]
})
df['date'] = pd.to_datetime(df['date'])
df_sales = df.pivot_table(index = ['region'], columns = ['date'], aggfunc = [np.sum], margins = True)
df_sales = df_sales.ix[:,range(0, df_sales.shape[1]-1)]
我的目标是对销售数据框df_sales执行以下操作。
创建一个新的数据框,按季度汇总销售额。我可以使用原始数据帧df或sales_df。
截至本季度,我们只有两个季度(USA fiscal calendar year),因此季度汇总数据框架如下所示:
2017Q1 2017Q2
10 27
31 37.5
133 139.17
我取决于第一季度所有日子的平均值,以及第二季度的平均值。因此,例如对于东北地区'NE'
,Q1是2017-03-30只有一天的平均值,即10,而Q2是2017-05-05到2017的平均值-04-20,即
(20+30+12+20+30+50)/6=27
有什么建议吗?
附加注意:理想情况下,我会在df_sales pivoted表上执行季度聚合,因为它是一个小得多的数据帧,可以保留在内存中。目前的解决方案是在原始df上完成的,但我仍在寻找在df_sales数据帧中实现它的方法。
答案 0 :(得分:1)
<强>更新强>
设定:
df.date = pd.to_datetime(df.date)
df_sales = df.pivot_table(index='region', columns='date', values='sales', aggfunc='sum')
In [318]: df_sales
Out[318]:
date 2017-03-30 2017-04-05 2017-04-07 2017-04-12 2017-04-13 2017-04-17 2017-04-20
region
NE 10 20 30 12 20 30 50
NW 31 33 31 35 39 49 38
SW 133 135 140 137 137 145 141
解决方案:
In [319]: (df_sales.groupby(pd.PeriodIndex(df_sales.columns, freq='Q'), axis=1)
...: .apply(lambda x: x.sum(axis=1)/x.shape[1])
...: )
Out[319]:
date 2017Q1 2017Q2
region
NE 10.0 27.000000
NW 31.0 37.500000
SW 133.0 139.166667
基于原始DF的解决方案:
In [253]: (df.groupby(['region', pd.PeriodIndex(df.date, freq='Q-DEC')])
...: .apply(lambda x: x['sales'].sum()/x['date'].nunique())
...: .to_frame('avg').unstack('date')
...: )
...:
Out[253]:
avg
date 2017Q1 2017Q2
region
NE 10.0 27.000000
NW 31.0 37.500000
SW 133.0 139.166667
注意:df
- 是原始DF(在“旋转”之前)