更快地在pandas数据帧中对子组中的行进行排名

cap*_*hab 21 python pandas

我有一个由不同子组组成的熊猫数据框.

    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]
    })
Run Code Online (Sandbox Code Playgroud)

我想在其组中找到每个id的等级,比如说,值越低越好.在上面的示例中,在组A中,Id 1的排名为1,Id 2的排名为4.在组B中,Id 5的排名为2,Id 8的排名为1,因此上.

现在我通过以下方式评估排名:

  1. 按值排序.

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

  2. 创建一个ranker函数(它假设变量已经排序)

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

  3. 分别对每个组应用排名功能:

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

这个过程有效,但是当我在数百万行数据上运行它时,它真的很慢.有没有人对如何制作更快的排名功能有任何想法.

Jef*_*eff 38

rank是cythonized所以应该非常快.你可以传递相同的选项,就像df.rank() 这里的文档一样rank.如您所见,可以通过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
Run Code Online (Sandbox Code Playgroud)


小智 10

使用一个大的DataFrame(1300万行),该方法与groupby的排名最大化了我的8GB RAM,这需要很长时间.我在内存中找到了一种不那么贪心的解决方法,我放在这里以防万一:

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
Run Code Online (Sandbox Code Playgroud)