Pandas多索引DataFrame:在第1级索引上进行分组时保留列的N个最大条目

时间:2015-12-15 06:08:12

标签: python sorting pandas

这是一个包含多索引行的DataFrame示例。

row_idx_arr = list(zip(['r0', 'r0', 'r0', 'r1', 'r1', 'r1', 'r2', 'r2', 'r2', 'r3', 'r3', 'r3'], ['r-00', 'r-01', 'r-02', 'r-00', 'r-01', 'r-02', 'r-00', 'r-01', 'r-02', 'r-00', 'r-01', 'r-02', ]))
row_idx = pd.MultiIndex.from_tuples(row_idx_arr)

d = pd.DataFrame((np.random.randn(36)*10).reshape(12,3), index=row_idx, columns=['c0', 'c1', 'returns'])


                c0         c1    returns
r0 r-00   3.553446   5.434018   5.141394
   r-01  10.045250  18.453873  13.170396
   r-02  -7.231743 -11.695715   5.303477
r1 r-00  -1.302917   6.461693  15.016544
   r-01  13.348552  -9.133629  -2.464875
   r-02  11.157144  16.833344  -8.745151
r2 r-00 -10.937900 -14.829996  -8.457521
   r-01  -7.495922   9.269724  -5.001560
   r-02  -8.966551  11.063291  -2.420552
r3 r-00 -21.434668  -0.730560   5.550830
   r-01  16.590447  -0.432384  -0.396881
   r-02  -0.636957  -2.765959   2.591906

我想创建一个新的DataFrame,其中,对于每个1级索引值(r0,r1,r2,r3),我保留2个条目(2级行:r-00,r-01,r- 02)具有最高'回报'。

请注意,这是一个例子,在我的程序中我有数千行。

2 个答案:

答案 0 :(得分:3)

我认为您可以nlargest使用groupby

import pandas as pd
import numpy as np

row_idx_arr = list(zip(['r0', 'r0', 'r0', 'r1', 'r1', 'r1', 'r2', 'r2', 'r2', 'r3', 'r3', 'r3'], ['r-00', 'r-01', 'r-02', 'r-00', 'r-01', 'r-02', 'r-00', 'r-01', 'r-02', 'r-00', 'r-01', 'r-02', ]))
row_idx = pd.MultiIndex.from_tuples(row_idx_arr)

d = pd.DataFrame((np.random.randn(36)*10).reshape(12,3), index=row_idx, columns=['c0', 'c1', 'returns'])
print d
                c0         c1    returns
r0 r-00 -13.417493 -14.758075  -3.650524
   r-01   1.092054  -1.224499  -8.968738
   r-02   4.793562  -9.958708 -16.554163
r1 r-00  -0.308835  -4.584725  -4.070714
   r-01 -23.764872   0.240768 -24.110720
   r-02  -4.054037   7.744689  12.762280
r2 r-00   9.160783 -16.041333  10.865837
   r-01 -10.472071  -1.625311  17.091514
   r-02 -13.009323   1.114351  -3.494279
r3 r-00   7.537877 -17.307256  -2.739447
   r-01  -1.107766   1.458901 -19.214064
   r-02   8.473581  -7.456646   1.427752
df = d.groupby(level=0, group_keys=False).apply(lambda x: x.nlargest(2, ['returns']))
print df
                c0         c1    returns
r0 r-00 -13.417493 -14.758075  -3.650524
   r-01   1.092054  -1.224499  -8.968738
r1 r-02  -4.054037   7.744689  12.762280
   r-00  -0.308835  -4.584725  -4.070714
r2 r-01 -10.472071  -1.625311  17.091514
   r-00   9.160783 -16.041333  10.865837
r3 r-02   8.473581  -7.456646   1.427752
   r-00   7.537877 -17.307256  -2.739447

答案 1 :(得分:0)

最优雅的方式如下:

d.groupby(axis=0, level=0, group_keys=False).nlargest(2, 'returns')

不幸的是,由于DataFrameGroupBy(由groupby返回的对象)还没有在Pandas API中实现了最大的方法,因此无法正常工作。

但这是一个解决方法:

larg = d['returns'].groupby(level=0, group_keys=False).nlargest(2)
d.ix[larg.index]

这是有效的,因为应用于Series的groupby会返回一个实现了最大方法的SeriesGroupBy对象。