2014-11-03 73 views
10

我有一个拥有不同子组的子熊猫数据框。在熊猫数据框的子组中排列行的更快方法

df = pd.DataFrame({ 
    'id':[1, 2, 3, 4, 5, 6, 7, 8], 
    'group':['a', 'a', 'a', 'a', 'b', 'b', 'b', 'b'], 
    'value':[.01, .4, .2, .3, .11, .21, .4, .01] 
    }) 

我想找到与发言权组的每个ID的等级,较低的值是更好的。在上面的例子中,在A组中,Id 1的秩为1,Id 2的秩为4.在组B中,Id 5的秩为2,Id 8的秩为1,所以上。

现在我通过评估等级:

  1. 按值排序。

    df.sort('value', ascending = True, inplace=True)

  2. 创建排名器函数(它假定已经排序变量)

    def ranker(df): df['rank'] = np.arange(len(df)) + 1 return df

  3. 分别涂抹在各组的排名器功能:

    df = df.groupby(['group']).apply(ranker)

这个过程有效,但是当我在数百万行数据上运行它时,它确实很慢。有没有人有任何想法如何使更快的排序功能。

回答

19

排名是cythonized所以应该是非常快。你可以通过相同的选项df.rank() hererank的文档。正如你所看到的,通过参数method可以用五种不同的方式之一进行抢七。

它也有可能你只是想组.cumcount()

In [12]: df.groupby('group')['value'].rank(ascending=False) 
Out[12]: 
0 4 
1 1 
2 3 
3 2 
4 3 
5 2 
6 1 
7 4 
dtype: float64 
+0

当然!有它的功能!也就是说,它和我上面的函数并不完全一样,因为如果有一个值绑定,我的函数将随机给一个id比另一个id具有相同的值更高的等级。尽管.rank()处理相同值的方式相当明智,但对于我的目的而言,我需要我的函数生成的输出。谢谢你的帮助! – 2014-11-03 19:56:36

+0

我更新了替代方案。 – Jeff 2014-11-03 21:25:35

9

使用一个大的DataFrame(1300万行),该方法与groupby排序最多我的8GB内存,它花了很长时间。我在内存中发现了一个不太贪心的解决方法,我只是为了防备:

df.sort_values('value') 
tmp = df.groupby('group').size() 
rank = tmp.map(range) 
rank =[item for sublist in rank for item in sublist] 
df['rank'] = rank 
相关问题