在Pandas Groupby中使用列和行多索引值而不进行取消堆栈

时间:2015-02-02 08:32:06

标签: python pandas multi-index

我有一个多索引层次结构设置如下:

import numpy as np

sectors = ['A','B','C','D']
ports = ['pf','bm']
dates = range(1,11)*2
wts, pchg = zip(*np.random.randn(20,2))
df = pd.DataFrame(dict(dates=dates,port=sorted(ports*10),
                       sector=np.random.choice(sectors,20), wts=wts,
                       pchg=pchg))

df = df.set_index(['port','sector','dates'])
df = df.unstack('port')
df = df.fillna(0)

我希望按datesport分组,并加pchg * wts

我一直在浏览文档,但我正在努力解决这个问题。

任何帮助非常感谢。感谢

1 个答案:

答案 0 :(得分:1)

你确实不需要取消堆栈来获得你想要的东西,使用product方法进行你想要的乘法。一步一步:

从这个数据框开始:

In [50]: df.head()
Out[50]:
                  pchg                 wts
port                bm        pf        bm        pf
sector dates
A      1      0.138996  0.451688  0.763287 -1.863401
       3      1.081863  0.000000  0.956807  0.000000
       4      0.207065  0.000000 -0.663175  0.000000
       5      0.258293 -0.868822  0.109336 -0.784900
       6     -1.016700  0.900241 -0.054077 -1.253191

我们可以首先使用product方法执行pchg * wts部分,乘以轴1,但仅适用于第二级:

In [51]: df.product(axis=1, level=1).head()
Out[51]:
port                bm        pf
sector dates
A      1      0.106094 -0.841675
       3      1.035134  0.000000
       4     -0.137320  0.000000
       5      0.028241  0.681938
       6      0.054980 -1.128174

然后我们可以按dates进行分组(并且不再需要按端口分组)并获取总和:

In [52]: df.product(axis=1, level=1).groupby(level='dates').sum()
Out[52]:
port         bm        pf
dates
1      0.106094 -0.841675
2      0.024968  1.357746
3      1.035134  1.776464
4     -0.137320  0.392312
5      0.028241  0.681938
6      0.054980 -1.128174
7      0.140183 -0.338828
8      1.296028 -1.526065
9     -0.213989  0.469104
10     0.058369 -0.006564

这提供与

相同的输出
df.stack('port').groupby(level=[1,2]).apply(lambda x: (x['wts']*x["pchg"]).sum()).unstack('port')