【Python】Pandas中的宝藏函数-rank()
所謂的排名,就是一組數據,我們想要知道每一條數據在整體中的名次,需要的是輸出名次,并不改變原數據結構。
排序會改變原來的數據結構,且不會返回名次,這一點區別需要弄明白。初學的時候容易弄混淆。
本文將通過一個實例,講清楚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’,但組之間的排名始終提高1
numeric_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.0?
2、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.0?
3、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.0?
4、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.0?
5、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 |
其他參數都比較簡單了,計算一行的排名,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?
碼字不易,大家多多分享傳播。求個點贊+在看。
往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習及深度學習筆記等資料打印機器學習在線手冊深度學習筆記專輯《統計學習方法》的代碼復現專輯 AI基礎下載機器學習的數學基礎專輯黃海廣老師《機器學習課程》視頻課 本站qq群851320808,加入微信群請掃碼:總結
以上是生活随笔為你收集整理的【Python】Pandas中的宝藏函数-rank()的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win10一键重装系统
- 下一篇: 【NLP】首个任务型对话系统中生成模块资