Python 手动计算多个列的秩平均值

Python 手动计算多个列的秩平均值,python,pandas,rank,Python,Pandas,Rank,我正在寻找一种基于多个列(其中一列包含字符串,另一列包含整数)生成使用average as方法的排名的方法(可以很容易地超过2列,但为了更简单的示例,我限制为2列) 其思想是能够创建按字符串降序排列和按整数升序排列的排名,这将是输出: Rank String Integer 0 2 c 4 1 2 c 4 2 2 c 4 3

我正在寻找一种基于多个列(其中一列包含字符串,另一列包含整数)生成使用average as方法的排名的方法(可以很容易地超过2列,但为了更简单的示例,我限制为2列)

其思想是能够创建按字符串降序排列和按整数升序排列的排名,这将是输出:

    Rank String  Integer
0      2      c        4           
1      2      c        4         
2      2      c        4          
3      4      c        6          
4      5      b        1          
5      6      b        3         
6      7      a        1            
7      8      a        2            
8    9.5      a        3            
9    9.5      a        3        
到目前为止,这是我设法做到的,但我在如何生成共享排名时的“平均值”方面遇到了麻烦

df['concat_values'] = df['String'] + df['Integer'].astype(str)  
df = df.sort_values(['String','Integer'],ascending=[False,True])
df = df.reset_index(drop=True).reset_index()
df['repeated'] = df.groupby('concat_values')['concat_values'].transform('count')
df['pre_rank'] = df['index'] + 1
df = df.sort_values('pre_rank')
df = df.drop('index',axis=1)
print(df)
  String  Integer concat_values  repeated  pre_rank
0      c        4            c4         3         1
1      c        4            c4         3         2
2      c        4            c4         3         3
3      c        6            c6         1         4
4      b        1            b1         1         5
5      b        3            b3         1         6
6      a        1            a1         1         7
7      a        2            a2         1         8
8      a        3            a3         2         9
9      a        3            a3         2        10
我考虑过使用一些过滤或公式,这样当列
repeated
的值大于1时,
pre_rank
会应用一个函数返回平均值,但该函数不能推广到所有行,它会对第一行起作用,但会对第二行产生更高的值(因为
pre\u rank
现在有更高的值)。我相信我只是错过了完成它的最后一步,但无法完成。谢谢!

我的方法:

df = df.sort_values(['String','Integer'], ascending=[False, True])
df['rank'] = np.arange(len(df)) + 1
df['rank'] = df.groupby(['String', 'Integer'])['rank'].transform('mean')
输出:

  String  Integer  rank
7      c        4   2.0
8      c        4   2.0
9      c        4   2.0
6      c        6   4.0
4      b        1   5.0
5      b        3   6.0
0      a        1   7.0
1      a        2   8.0
2      a        3   9.5
3      a        3   9.5
排序
+
分组
+
排名
。 要求您在groupby中指定
sort=False
,以便按照您排序的顺序生成
ngroup
标签

df = df.sort_values(['String', 'Integer'], ascending=[False, True])
df['rank'] = df.groupby(['String', 'Integer'], sort=False).ngroup().rank()


大量使用
ngroup
这正是我所做的…除了
range(1,len(df)+1)
(:为什么
c
的秩是2而不是1或3?因为c4对秩1,2,3重复。使用method=average为每行分配相同的秩(值秩的平均值),因此,c4将具有秩2=((1+2+3)/2)
df = df.sort_values(['String', 'Integer'], ascending=[False, True])
df['rank'] = df.groupby(['String', 'Integer'], sort=False).ngroup().rank()
  String  Integer  rank
7      c        4   2.0
8      c        4   2.0
9      c        4   2.0
6      c        6   4.0
4      b        1   5.0
5      b        3   6.0
0      a        1   7.0
1      a        2   8.0
2      a        3   9.5
3      a        3   9.5