图解Pandas的排名rank机制

图解Pandas的排名rank机制

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

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

image

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 pd
import numpy as np

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

image

参数method

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

image

2、method="first"

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

image

解释上面两个结果:

  • first:直接根据数值的大小顺序进行排名
  • average:表示的是,如果两个数值相同,排名是它们的均值
image

我们看到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的使用

[图片上传失败...(image-d9f522-1625217642139)]

image

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

4、method="dense"

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

image

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

参数ascending

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

image
image

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

image

参数pct

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

image

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

image
image

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

image

参数na_option

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

image

看看3种不同的情况:

image
image
image

DataFrame排名

模拟数据

还是先模拟一份数据:

df0 = pd.DataFrame({"科目":["语文","语文","语文","语文","语文","数学","数学","数学","数学","数学"],
                  "姓名":["小明","小苏","小周","小孙","小王","小明","小苏","小周","小孙","小王"],
                  "分数":[137,125,125,115,115,80,111,130,130,140]})

df = df0.copy()   # 生成一个副本df
df
image

单个科目排名

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

image

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

# 默认排名方式

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
image

同学总分排名

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

df["总分"] = df.groupby("姓名")["分数"].transform("sum")
df
image

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

image

分组取出指定排名

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

# 定义一个排名第二的函数

def rank_second(x):
    return x[x["分数"].rank(method="dense",ascending=False) == 2]
image

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

image

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

1、先实现密集排名

image

2、指定排名等于2

image

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

总结

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

  • row_number:顺序排名,rank函数的中的method=first
  • rank:跳跃排名,rank函数的中的method=min
  • dense_rank:密集排名,rank函数的中的method=dense
image

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

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容