熊猫 - 在groupby中排序并进行排序

时间:2016-12-26 11:43:14

标签: python pandas dataframe group-by

我有以下数据框:

                       uniq_id    value
2016-12-26 11:03:10        001      342
2016-12-26 11:03:13        004        5
2016-12-26 12:03:13        005       14
2016-12-26 12:03:13        008      114
2016-12-27 11:03:10        009      343
2016-12-27 11:03:13        013        5
2016-12-27 12:03:13        016      124
2016-12-27 12:03:13        018      114

我需要按价值排序每天获得前N个记录。 这样的事情(对于N = 2):

2016-12-26   001   342
             008   114
2016-12-27   009   343
             016   124

请在pandas 0.19.x

中建议正确的方法

2 个答案:

答案 0 :(得分:4)

不幸的是,还没有DataFrameGroupBy.nlargest()这样的方法,这将允许我们执行以下操作:

df.groupby(...).nlargest(2, columns=['value'])

所以这里有点难看但是有效的解决方案:

In [73]: df.set_index(df.index.normalize()).reset_index().sort_values(['index','value'], ascending=[1,0]).groupby('index').head(2)
Out[73]:
       index  uniq_id  value
0 2016-12-26        1    342
3 2016-12-26        8    114
4 2016-12-27        9    343
6 2016-12-27       16    124

PS我觉得一定有更好的......

更新:如果您的DF没有重复的索引值,以下解决方案也应该有效:

In [117]: df
Out[117]:
                     uniq_id  value
2016-12-26 11:03:10        1    342
2016-12-26 11:03:13        4      5
2016-12-26 12:03:13        5     14
2016-12-26 12:33:13        8    114    # <-- i've intentionally changed this index value
2016-12-27 11:03:10        9    343
2016-12-27 11:03:13       13      5
2016-12-27 12:03:13       16    124
2016-12-27 12:33:13       18    114    # <-- i've intentionally changed this index value

In [118]: df.groupby(pd.TimeGrouper('D')).apply(lambda x: x.nlargest(2, 'value')).reset_index(level=1, drop=1)
Out[118]:
            uniq_id  value
2016-12-26        1    342
2016-12-26        8    114
2016-12-27        9    343
2016-12-27       16    124

答案 1 :(得分:2)

df.set_index('uniq_id', append=True) \
    .groupby(df.index.date).value.nlargest(2) \
    .rename_axis([None, None, 'uniq_id']).reset_index(-1)


                                uniq_id  value
2016-12-26 2016-12-26 11:03:10        1    342
           2016-12-26 12:03:13        8    114
2016-12-27 2016-12-27 11:03:10        9    343
           2016-12-27 12:03:13       16    124