【问题标题】:Rank by grouby column aggregate按 grouby 列聚合排名
【发布时间】:2016-05-16 05:59:30
【问题描述】:

我想创建一个列manager_rank,根据回报的sum 对经理进行排名。我想出了下面发布的一种解决方案,但希望其他人有更优雅的东西。

import pandas as pd
df = pd.DataFrame([['2012', 'A', 1], ['2012', 'B', 4], ['2011', 'A', 5], ['2011', 'B', 4]],
                 columns=['year', 'manager', 'return'])

想要的结果:

   year manager  return  manager_rank
0  2012       A       1             2
1  2011       A       5             2
2  2012       B       4             1
3  2011       B       4             1

【问题讨论】:

    标签: python pandas


    【解决方案1】:
    df['ranking'] = df.groupby('manager')['return'].transform(np.sum).rank(ascending=False, method='dense')
    
       year manager  return  ranking
    0  2012       A       1        2
    1  2012       B       4        1
    2  2011       A       5        2
    3  2011       B       4        1
    

    【讨论】:

      【解决方案2】:

      您可以删除to_frame并将name添加到reset_index

      manager_rank = (df.groupby('manager')
                        .sum()
                        ['return']
                        .rank(ascending=False)
                        .reset_index(name='manager_rank')
                      )
      
      df = pd.merge(df, manager_rank, on='manager')
      print df
      
         year manager  return  manager_rank
      0  2012       A       1             2
      1  2011       A       5             2
      2  2012       B       4             1
      3  2011       B       4             1
      

      【讨论】:

        【解决方案3】:

        如何扩展@Stefan 提出的方法以包括每个经理的最终累积回报(回报不相加,它们是复合的)。

        df['total_return'] = (df
                              .groupby('manager')['return']
                              .transform(lambda group: (1 + group / 100.).cumprod().iat[-1])) - 1
        df['ranking'] = df.total_return.rank(ascending=False, method='dense')
        
        >>> df
           year manager  return  ranking  total_return
        0  2012       A       1        2        0.0605
        1  2012       B       4        1        0.0816
        2  2011       A       5        2        0.0605
        3  2011       B       4        1        0.0816
        

        【讨论】:

        • 这是显示累积回报的绝佳方式。我应该将列命名为 return_pct :-(.
        • 这是另一个问题的好答案。
        【解决方案4】:

        单线:

        manager_rank = (df.groupby('manager')
                          .sum()
                          ['return']
                          .rank(ascending=False)
                          .to_frame(name='manager_rank')
                          .reset_index()
                        )
        
        df = pd.merge(df, manager_rank, on='manager')
        

        分步详细信息:

        1。以sum为聚合函数的Manager分组

        In [8]: df.groupby('manager').sum()
        Out[8]: 
                 return
        manager        
        A             6
        B             8
        

        2。使用rank() 为经理分配等级

        In [9]: df.groupby('manager').sum().rank()
        Out[9]: 
                 return
        manager        
        A             1
        B             2
        
        In [10]: df.groupby('manager').sum().rank(ascending=False)
        Out[10]: 
                 return
        manager        
        A             2
        B             1
        

        3。将此结果投射到另一列

        In [13]: df.groupby('manager').sum().rank(ascending=False)['return'].to_frame(name='manager_rank')
        Out[13]: 
                 manager_rank
        manager              
        A                   2
        B                   1
        

        4。将上述步骤的结果与原始数据框连接起来!

        df = pd.merge(df, manager_rank, on='manager')
        

        【讨论】:

          猜你喜欢
          • 2013-02-03
          • 2014-10-05
          • 2017-10-18
          • 1970-01-01
          • 2021-02-05
          • 2011-11-25
          • 2015-02-10
          • 2014-11-17
          • 1970-01-01
          相关资源
          最近更新 更多