按grouby列聚合排名

时间:2015-12-28 18:42:54

标签: python pandas

我想创建一个列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

4 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:1)

一衬垫:

r-base-dev

分步详情:

1。按经理分组,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') 作为聚合功能

sum

2。使用In [8]: df.groupby('manager').sum() Out[8]: return manager A 6 B 8 为管理员分配排名

rank()

3。将此结果转换为另一列

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

4。用原始数据框加入上述步骤的结果!

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

答案 2 :(得分:1)

您可以删除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 :(得分:1)

如何扩展@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