Pandas中的宝藏函数-rank()
本文转载自微信公众号「AI入门学习」,宝藏作者小伍哥 。函数转载本文请联系AI入门学习公众号。宝藏
所谓的函数排名,就是宝藏一组数据,我们想要知道每一条数据在整体中的函数名次,需要的宝藏是输出名次,并不改变原数据结构。函数
排序会改变原来的宝藏数据结构,且不会返回名次,函数这一点区别需要弄明白。宝藏初学的函数时候容易弄混淆。
本文将通过一个实例,宝藏讲清楚Pandas中rank()排名函数的函数应用。下面是宝藏案例数据,包括我、张三以及唐宋八大家的语文考试成绩。
import pandas as pd data = pd.DataFrame({ 班级:[1班,1班,1班,1班,1班,2班,2班,2班,2班,2班], 姓名:[韩愈,柳宗元,欧阳修,苏洵,苏轼,苏辙,曾巩,王安石,张三,小伍哥], 成绩:[80,70,70,40,10,60,60,50,50,40]}) #姓名长度不一样的,加个符号调整下,这该死的强迫症 data[姓名] = data[姓名].str.rjust(3,〇)一、DataFrame的正常排名
Pandas中的云服务器提供商排名,函数为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’,但组之间的排名始终提高1numeric_only:bool,是否仅仅计算数字型的columns,布尔值
na_option:{ keep,top,bottom},默认为keep,NaN值是服务器托管否参与排名及如何排名
keep:将NaN等级分配给NaN值 top:如果升序,则将最小等级分配给NaN值 bottom:如果升序,则将最高等级分配给NaN值。ascending:bool,默认为True,元素是否应该按升序排名。
pct:bool,默认为False,是否以百分比形式显示返回的排名。
所有的参数中,最核心的参数是method,一共5种排名方法,下面对这5种方法进行对比,应用的时候更好的去选择。
1、method=first
当method=first时,当里两个人的分数相同时,分数相同的情况下,谁先出现谁的排名靠前(当method取值为min,max,average时,都是亿华云计算要参考“顺序排名”的),表中的柳宗元和欧阳修分数相同,但是柳宗元在表格的前面,所以排名第2,欧阳修排名第3。
班级
姓名
成绩
成绩(method=first)
1班
〇韩愈
50
1
1班
柳宗元
30
2
1班
欧阳修
30
3
1班
〇苏洵
20
4
1班
〇苏轼
10
5
代码如下:
#为了简化,我们只选择1班的成绩来看 data_1 = data[data[班级]==1班] data_1[成绩_first] = data_1[成绩].rank(method=first,ascending=False) data_1 班级 姓名 成绩 成绩_first 0 1班 〇韩愈 50 1.0 1 1班 柳宗元 30 2.0 2 1班 欧阳修 30 3.0 3 1班 〇苏洵 20 4.0 4 1班 〇苏轼 10 5.02、method=min
当method=min时,成绩相同的同学,取在顺序排名中最小的那个排名作为该值的排名,会出现名次跳空,柳宗元和欧阳修分数相同,在上面的排名中,分别排第2、第3,所以这里取两个中最小的为排名名次2作为共同的名次。
班级
姓名
成绩
成绩(method=min)
1班
〇韩愈
50
1
1班
柳宗元
30
2
1班
欧阳修
30
2
1班
〇苏洵
20
4
1班
〇苏轼
10
5
代码如下:
data_1 = data[data[班级]==1班] data_1[成绩_min] = data_1[成绩].rank(method=min,ascending=False) data_1 班级 姓名 成绩 成绩_min 0 1班 〇韩愈 50 1.0 1 1班 柳宗元 30 2.0 2 1班 欧阳修 30 2.0 3 1班 〇苏洵 20 4.0 4 1班 〇苏轼 10 5.03、method=max
当method=max时,与上面的min相反,成绩相同的同学,取在顺序排名中最大的那个排名作为该值的排名,,会出现名次跳空,柳宗元和欧阳修分数相同,在顺序排名中,分别排第2、第3,所以这里取两个中最大的为排名名次3作为共同的名次。
班级
姓名
成绩
成绩_max
1班
〇韩愈
50
1
1班
柳宗元
30
3
1班
欧阳修
30
3
1班
〇苏洵
20
4
1班
〇苏轼
10
5
代码如下:
data_1 = data[data[班级]==1班] data_1[成绩_max] = data_1[成绩].rank(method=max,ascending=False) data_1 班级 姓名 成绩 成绩_max 0 1班 〇韩愈 50 1.0 1 1班 柳宗元 30 3.0 2 1班 欧阳修 30 3.0 3 1班 〇苏洵 20 4.0 4 1班 〇苏轼 10 5.04、method=dense
method=dense,dense是稠密的意思,即相同成绩的同学排名相同,其他依次加1即可,不会出现名次跳空的情况。柳宗元和欧阳修分数相同,在上面的排名中,分别排第2、第3,取相同排名2,这个看上去和min一样的,但是下一名的排名发生了变化,〇苏洵同学从第4名排到了第3名,排名数字连续的,没有跳跃。
班级
姓名
成绩
成绩_dense
1班
〇韩愈
50
1
1班
柳宗元
30
2
1班
欧阳修
30
2
1班
〇苏洵
20
3
1班
〇苏轼
10
4
代码如下:
data_1 = data[data[班级]==1班] data_1[成绩_dense] = data_1[成绩].rank(method=dense,ascending=False) data_1 班级 姓名 成绩 成绩_dense 0 1班 〇韩愈 50 1.0 1 1班 柳宗元 30 2.0 2 1班 欧阳修 30 2.0 3 1班 〇苏洵 20 3.0 4 1班 〇苏轼 10 4.05、method=average
当method=average或者默认值时,成绩相同时,取顺序排名中所有名次之和除以该成绩的个数,即为该成绩的名次;比如上述排名中,30排名为2,3,那么 30的排名 = (2+3)/2=2.5,成绩为50的同学只有1个,且排名为1,那50的排名就位1/1=1。
班级
姓名
成绩
成绩_average
1班
〇韩愈
50
1
1班
柳宗元
30
2.5
1班
欧阳修
30
2.5
1班
〇苏洵
20
4
1班
〇苏轼
10
5
代码如下:
data_1 = data[data[班级]==1班] data_1[成绩_average] = data_1[成绩].rank(method=average,ascending=False) data_1 班级 姓名 成绩 成绩_average 0 1班 〇韩愈 50 1.0 1 1班 柳宗元 30 2.5 2 1班 欧阳修 30 2.5 3 1班 〇苏洵 20 4.0 4 1班 〇苏轼 10 5.0综合上面的所有排名类型类型整体对比看看:
班级
姓名
成绩
rank
rank_min
rank_max
rank_first
rank_dense
1班
〇韩愈
50
1
1
1
1
1
1班
柳宗元
30
2.5
2
3
2
2
1班
欧阳修
30
2.5
2
3
3
2
1班
〇苏洵
20
4
4
4
4
3
1班
〇苏轼
10
5
5
5
5
4
data_1 = data[data[班级]==1班] data_1[rank] = data_1[成绩].rank(ascending=False) data_1[rank_min] = data_1[成绩].rank(method=min,ascending=False) data_1[rank_max] = data_1[成绩].rank(method=max,ascending=False) data_1[rank_first] = data_1[成绩].rank(method=first,ascending=False) data_1[rank_dense] = data_1[成绩].rank(method=dense,ascending=False) data_1 班级 姓名 成绩 rank rank_min rank_max rank_first rank_dense 0 1班 〇韩愈 50 1.0 1.0 1.0 1.0 1.0 1 1班 柳宗元 30 2.5 2.0 3.0 2.0 2.0 2 1班 欧阳修 30 2.5 2.0 3.0 3.0 2.0 3 1班 〇苏洵 20 4.0 4.0 4.0 4.0 3.0 4 1班 〇苏轼 10 5.0 5.0 5.0其他参数都比较简单了,计算一行的排名,axis=0即可。
参数pct=True时,返回排名的分位数,可以用于计算排名的百分比,非常方便。
data_1 = data[data[班级]==1班] data_1[成绩_first] = data_1[成绩].rank(method=first, ascending=False, pct=True) data_1 班级 姓名 成绩 成绩_first 0 1班 〇韩愈 80 0.2 1 1班 柳宗元 70 0.4 2 1班 欧阳修 70 0.6 3 1班 〇苏洵 40 0.8 4 1班 〇苏轼 10 1.0二、DataFrame的分组排名
在上文中,我们看到了rank()函数对DataFrame直接排名,非常方便,也非常丰富,当然,rank()也可以对经过groupby分组后的数据进行排名,分组排名的功能,让数据分析更加的精细化,大大提高分析效率。直接使用开头创建好的数据集,按班级排名,看看乜咯班级的第一名是谁。
data[成绩_dense]= data.groupby(班级)[成绩].rank(method=dense) data 班级 姓名 成绩 成绩_dense 0 1班 〇韩愈 50 4.0 1 1班 柳宗元 30 3.0 2 1班 欧阳修 30 3.0 3 1班 〇苏洵 20 2.0 4 1班 〇苏轼 10 1.0 5 2班 〇苏辙 60 3.0 6 2班 〇曾巩 60 3.0 7 2班 王安石 50 2.0 8 2班 〇张三 50 2.0 9 2班 小伍哥 40 1.0同上面的直接排名,method一样的可以使用各种方法,达到各种排名的目的。
data[成绩_average]= data.groupby(班级)[成绩].rank(method=average) data 班级 姓名 成绩 成绩_average 0 1班 〇韩愈 80 5.0 1 1班 柳宗元 70 3.5 2 1班 欧阳修 70 3.5 3 1班 〇苏洵 40 2.0 4 1班 〇苏轼 10 1.0 5 2班 〇苏辙 60 4.5 6 2班 〇曾巩 60 4.5 7 2班 王安石 50 2.5 8 2班 〇张三 50 2.5 9 2班 小伍哥 40 1.0三、Series的排名
对于Series。其实就是数据框的一列,没啥多说的,一样的方法就行,下面写了两个简单的示例,大家参考下。
from pandas import Series s = Series([1,3,2,1,6]) s.rank() a 1.5 c 4.0 d 3.0 b 1.5 e 5.0根据值在数组中出现的顺序进行排名,method=first
s.rank(method=first) a 1.0 c 4.0 d 3.0 b 2.0 e 5.0根据值在数组中出现的顺序密集排名,method=dense
s.rank(method=dense) a 1.0 c 3.0 d 2.0 b 1.0 e 4.0【编辑推荐】
如何查询你的Pandas数据帧? 好习惯!pandas 8 个常用的 index 设置 Python‖零基础入门Pandas 大数据 Python数据分析处理库-pandas实战视频课程 这20个Pandas函数,堪称“数据清洗”杀手!