写点什么

图解 Pandas 的排名 rank 机制

用户头像
Peter
关注
发布于: 1 小时前
图解Pandas的排名rank机制

图解 Pandas 的排名 rank 机制

在我们的生活经常会遇到各种排名问题:学生成绩排名、销售员业绩排名、各种比赛排名等。在之前一篇关于 SQL 的文章-《面试必备:SQL 排名和窗口函数》中有提到过如何使用 SQL 来实现 3 种主要的排名方式:顺序排名、跳跃排名和密集排名。


Pandas 这个强大的数据分析库也可以快速实现多种排名方式,主要是通过 rank 函数来解决的,本文将通过多个例子来讲解。



Rank 参数

下面是 rank 函数的主要参数为:


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


参数的具体解释为:


  • axis:表示排名是根据哪个轴,axis=0 表示横轴,axis=1 表示纵轴

  • method:取值可以为'average','first','min', 'max','dense';后面重点介绍,默认是 average

  • numeric_only:是否仅仅计算数字型的 columns

  • na_optiaon:NaN 值是否参与排名以及如何排名,取值为 keep、top、bottom

  • ascending:升序还是降序;默认是升序

  • pct:是否以排名的百分比显示排名;所有排名和最大排名的百分比


本文将会讲解 rank 函数在 Series 和 DataFrame 两种数据类型的使用。

Series 排名

import pandas as pdimport numpy as np
复制代码


首先我们模拟一份简单的数据:


参数 method

1、默认情况的排名 method="average":



2、method="first"


根据值在原始数据中出现的顺序进行排名,相同数值的排名依次加 1:



解释上面两个结果:


  • first:直接根据数值的大小顺序进行排名

  • average:表示的是,如果两个数值相同,排名是它们的均值



我们看到 first 的使用就是数值的自然顺序出现的排名;在使用 average 的情况解释如下:


-5 的排名是 1.0,0 的排名是 2.0,3 的排名是 3.0,5(3 号索引位置)的排名是 4.0,5(6 号索引位置)的排名是 5.0,8(0 号索引位置)的排名是 6.0,8(2 号索引)的排名是 7.0


通过 average 的使用,相同数值的排名 rank 会取出均值,5 的排名统一成 4.5,8 的排名统一成 6.5


3、max 和 min 的使用




比如当:method= "max":如果数值相同,取该数值最大的那个排名。比如 5 最大的排名是 5,所以原始数据中两个 5 的排名都是 5;两个 8 的排名都是 7(8 的两个排名是 6 和 7,取大值 7)


4、method="dense"


相同的数值排名相同,下个数值的排名不出现跳跃



这个时候排名的时候是不会出现跳跃的情况

参数 ascending

默认情况下是升序的情况,可以使用降序:值越大,排名越靠前:




数值中 8 的排名,如果是 method=“first”,排名是 1 和 2,如是使用 average,排名则会变成 1.5;其他的数值排名类似。再看看 max 的情况:


参数 pct

是否以排名的百分比显示排名;所有排名和最大排名的百分比



上面的排名是如何计算出来的呢?我们最大的排名是 7:




再比如 dense 情况下的 pct 参数使用类似:


参数 na_option

这个参数表示的是空值是否参与排名,取值为 keep、top、bottom。我们再模拟一份带有空值的数据:



看看 3 种不同的情况:




DataFrame 排名

模拟数据

还是先模拟一份数据:


df0 = pd.DataFrame({"科目":["语文","语文","语文","语文","语文","数学","数学","数学","数学","数学"],                  "姓名":["小明","小苏","小周","小孙","小王","小明","小苏","小周","小孙","小王"],                  "分数":[137,125,125,115,115,80,111,130,130,140]})
df = df0.copy() # 生成一个副本dfdf
复制代码


单个科目排名

比如我们想看语文这门科目的排名情况,取出同学们的语文成绩:



分别使用顺序排名、跳跃排名和密集排名来展示排名情况:


# 默认排名方式
df1["均值排名_默认"] = df1["分数"].rank(ascending=False)df1["跳跃排名_min"] = df1["分数"].rank(method="min",ascending=False)df1["跳跃_max"] = df1["分数"].rank(method="max",ascending=False)df1["密集排名_dense"] = df1["分数"].rank(method="dense",ascending=False)
df1
复制代码


同学总分排名

先通过 transform 生成每个同学的总分:


df["总分"] = df.groupby("姓名")["分数"].transform("sum")df
复制代码



我们使用密集排名的方式对总分进行排名:


分组取出指定排名

我们现在看到每个科目下的第二名的学生,如果成绩相同,排名相同(不跳跃),我们使用密集排名:


# 定义一个排名第二的函数
def rank_second(x): return x[x["分数"].rank(method="dense",ascending=False) == 2]
复制代码



我们看看真实数据中每个科目的第二名同学:



上面自定义的排名第二的函数分为两步;


1、先实现密集排名



2、指定排名等于 2



当我们使用这个自定义函数的时候,我们需要先根据科目进行分组,然后再每个组中单独使用这个自定义函数,就能获得每个科目下的第二名。

总结

讲解完 rank 函数的使用,可以和 SQL 中的窗口函数进行类比:


  • row_number:顺序排名,rank 函数的中的 method=first

  • rank:跳跃排名,rank 函数的中的 method=min

  • dense_rank:密集排名,rank 函数的中的 method=dense



最后附上 rank 函数的官网学习地址,还得多看官网:


https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.rank.html

发布于: 1 小时前阅读数: 5
用户头像

Peter

关注

志之所趋,无远弗届,穷山距海,不能限也。 2019.01.15 加入

还未添加个人简介

评论

发布
暂无评论
图解Pandas的排名rank机制