【问题标题】:Faster way to rank rows in subgroups in pandas dataframe在熊猫数据框中对子组中的行进行排名的更快方法
【发布时间】:2019-03-15 09:55:27
【问题描述】:

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

    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)

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

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    rank 是 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
    

    【讨论】:

    • 当然!它有一个功能!也就是说,它与我上面的函数做的事情并不完全相同,因为如果值存在关联,我的函数将随机赋予一个 id 比具有相同值的另一个 id 更高的排名。尽管 .rank() 处理相同值的方式相当明智,但出于我的目的,我需要函数产生的输出。感谢您的帮助!
    【解决方案2】:

    使用大型 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
    

    【讨论】:

      猜你喜欢
      • 2014-11-07
      • 1970-01-01
      • 2019-04-12
      • 2015-02-02
      • 2012-06-19
      • 2022-11-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多