Press "Enter" to skip to content

Pandas rank()排名函数

rank是通过“为各组分配一个平均排名”的方式破坏平级关系的。pandas排名会增加一个排名值(从1开始,一直到数组中有效数据的数量)。

所谓的排名,就是一组数据,我们想要知道每一条数据在整体中的名次,需要的是输出名次,并不改变原数据结构。

而排序会改变原来的数据结构,且不会返回名次,这一点区别需要弄明白。初学的时候容易弄混淆。

本文将通过一个实例,讲清楚Pandas中rank()排名函数的应用。下面是案例数据,包括我、张三以及唐宋八大家的语文考试成绩。

import pandas as pd
df = pd.DataFrame({'班级':['1班','1班','1班','1班','1班','2班','2班','2班','2班','2班'],
'姓名':['韩愈','柳宗元','欧阳修','苏洵','苏轼','苏辙','曾巩','王安石','张三','小伍哥'],
'成绩':[80,70,70,40,10,60,60,50,50,40]})

print(df)

结果:

  班级    姓名  成绩
0  1班    韩愈    80
1  1班  柳宗元    70
2  1班  欧阳修    70
3  1班    苏洵    40
4  1班    苏轼    10
5  2班    苏辙    60
6  2班    曾巩    60
7  2班  王安石    50
8  2班    张三    50
9  2班  小伍哥    40

rank()函数语法:

DataFrame.rank(axis=0,method='average',numeric_only=None,na_option='keep',ascending=True,pct=False)

参数说明:

axis:0或’index’,1或’columns’,默认0,沿着行或列计算排名

method:’average’,’min’,’max’,’first’,’dense’,默认为’average’,如何对具有相同值(即ties)的记录组进行排名:

average:组的平均等级
min:组中最低的排名
max:组中最高等级
first:按排列顺序排列,依次排列
dense:类似于 ‘min’,但组之间的排名始终提高1

ascending:bool,默认为True(升序),元素是否应该按升序排名,如果为False就是降序

pct:bool,默认为False,是否以百分比形式显示返回的排名

所有的参数中,最核心的参数是method,一共5种排名方法,下面对这5种方法进行对比,应用的时候更好的去选择。


1、method=’first’

当method=’first’时,当里两个人的分数相同时,分数相同的情况下,谁先出现谁的排名靠前(当method取值为min,max,average时,都是要参考“顺序排名”的),表中的柳宗元和欧阳修分数相同,但是柳宗元在表格的前面,所以排名第2,欧阳修排名第3。

df['成绩排名_first'] =df.groupby('班级')['成绩'].rank(method='first', ascending=False)

结果如下:

  班级    姓名  成绩  成绩排名_first
0  1班    韩愈    80        1.000000
1  1班  柳宗元    70        2.000000
2  1班  欧阳修    70        3.000000
3  1班    苏洵    40        4.000000
4  1班    苏轼    10        5.000000
5  2班    苏辙    60        1.000000
6  2班    曾巩    60        2.000000
7  2班  王安石    50        3.000000
8  2班    张三    50        4.000000
9  2班  小伍哥    40        5.000000

2、method=’min’

当method=’min’时,成绩相同的同学,取在顺序排名中最小的那个排名作为该值的排名,会出现名次跳空,柳宗元和欧阳修分数相同,在上面的排名中,分别排第2、第3,所以这里取2和3的最小的那个作为第2名作为共同的名次。

df['成绩排名_min'] =df.groupby('班级')['成绩'].rank(method='min', ascending=False)

结果如下:

  班级    姓名  成绩  成绩排名_min
0  1班    韩愈    80      1.000000
1  1班  柳宗元    70      2.000000
2  1班  欧阳修    70      2.000000
3  1班    苏洵    40      4.000000
4  1班    苏轼    10      5.000000
5  2班    苏辙    60      1.000000
6  2班    曾巩    60      1.000000
7  2班  王安石    50      3.000000
8  2班    张三    50      3.000000
9  2班  小伍哥    40      5.000000

3、method=’max’

当method=’max’时,与上面的min相反,成绩相同的同学,取在顺序排名中最大的那个排名作为该值的排名,会出现名次跳空,柳宗元和欧阳修分数相同,在顺序排名中,分别排第2、第3,所以这里取2和3当中的最大的那个作为第3名作为共同的名次。

df['成绩排名_max'] =df.groupby('班级')['成绩'].rank(method='max', ascending=False)
  班级    姓名  成绩  成绩排名_max
0  1班    韩愈    80      1.000000
1  1班  柳宗元    70      3.000000
2  1班  欧阳修    70      3.000000
3  1班    苏洵    40      4.000000
4  1班    苏轼    10      5.000000
5  2班    苏辙    60      2.000000
6  2班    曾巩    60      2.000000
7  2班  王安石    50      4.000000
8  2班    张三    50      4.000000
9  2班  小伍哥    40      5.000000

4、method=’dense’

method=’dense’,dense是密集的意思,即相同成绩的同学排名相同,其他依次加1即可,不会出现名次跳空的情况。柳宗元和欧阳修分数相同,在上面的排名中,分别排第2、第3,取相同排名2,这个看上去和min一样的,但是下一名的排名发生了变化,苏洵同学从第4名排到了第3名,排名数字连续的,没有跳跃。

df['成绩排名_dense'] =df.groupby('班级')['成绩'].rank(method='dense', ascending=False)
  班级    姓名  成绩  成绩排名_dense
0  1班    韩愈    80        1.000000
1  1班  柳宗元    70        2.000000
2  1班  欧阳修    70        2.000000
3  1班    苏洵    40        3.000000
4  1班    苏轼    10        4.000000
5  2班    苏辙    60        1.000000
6  2班    曾巩    60        1.000000
7  2班  王安石    50        2.000000
8  2班    张三    50        2.000000
9  2班  小伍哥    40        3.000000

5、method=’average’

当method=’average’或者默认值时,成绩相同时,取顺序排名中所有名次之和除以该成绩的个数,即为该成绩的名次;比如上述排名中,70排名为2,3,那么,70的排名 = (2+3)/2=2.5,成绩为80的同学只有1个,且排名为1,那80的排名就位1/1=1。

  班级    姓名  成绩  成绩排名_average
0  1班    韩愈    80          1.000000
1  1班  柳宗元    70          2.500000
2  1班  欧阳修    70          2.500000
3  1班    苏洵    40          4.000000
4  1班    苏轼    10          5.000000
5  2班    苏辙    60          1.500000
6  2班    曾巩    60          1.500000
7  2班  王安石    50          3.500000
8  2班    张三    50          3.500000
9  2班  小伍哥    40          5.000000

发表评论

您的电子邮箱地址不会被公开。