iT邦幫忙

2024 iThome 鐵人賽

DAY 16
0

本篇文章同步發布於 Python pandas 使用 rank 得到排名【Python 處理 Excel #16】

前言

進行資料分析時,前幾名的資料總是讓人特別感興趣,這篇文章介紹如何使用 Python pandas 的 rank 方法得到 DataFrame 資料的排名。


文章案例說明

文章中使用 example.xlsx 作為說明用的案例資料。example.xlsx 的內容如下:

order_id customer_name order_quantity unit_price
10000 Amy Chen 45 1000
10001 Grace Liu 165 1000
10002 Ivy Yang 265 1200
10003 David Lee 120 1000
10004 Amy Chen 115 1000
10005 Amy Chen 60 1200
10006 Bob Wang 265 1500
10007 Charlie Lin 250 1000
10008 Amy Chen 145 1200
10009 Emma Huang 30 1500

按訂單金額對訂單進行排名

下方程式碼先增加訂單總金額欄位,並根據總金額對訂單進行排名。

import pandas as pd

# 讀取訂單資料
df = pd.read_excel("example.xlsx")

# 新增總金額欄位
df['order_amount'] = df['order_quantity'] * df['unit_price']

# 根據訂單總金額進行排名,並新增排名欄位
df['order_rank'] = df['order_amount'].rank(ascending=False, method='min')

# 輸出訂單編號、總金額和排名
print(df[['order_id', 'order_amount', 'order_rank']])

解釋

  • df['order_rank'] = df['order_amount'].rank(ascending=False, method='min'):使用 rank() 根據訂單總金額進行排名,參數 ascending=False 表示從高到低排名,method='min' 表示如果有相同的金額,將用最小的排名分配當作有相同金額的訂單的排名。

按客戶總訂單數量排名

下方程式碼利用之前介紹過的 groupby 方法加總每個客戶的總訂單數量,然後依據每位客戶的總訂單數量進行排名。

import pandas as pd

# 讀取訂單資料
df = pd.read_excel("example.xlsx")

# 按客戶分組,計算每位客戶的總訂單數量
customer_order_sum = df.groupby('customer_name')['order_quantity'].sum().reset_index()

# 根據總訂單數量進行排名
customer_order_sum['customer_rank'] = customer_order_sum['order_quantity'].rank(ascending=False, method='min')

# 輸出客戶名稱、總訂單數量和排名
print(customer_order_sum[['customer_name', 'order_quantity', 'customer_rank']])

解釋

  • customer_order_sum = df.groupby('customer_name')['order_quantity'].sum().reset_index():使用 groupby() 根據 customer_name 對訂單數量進行分組,並計算每位客戶的總訂單數量。reset_index() 則將分組結果轉換回 DataFrame。
  • customer_order_sum['customer_rank'] = customer_order_sum['order_quantity'].rank(ascending=False, method='min'):使用 rank() 根據總訂單數量進行排名,採用從數量大到數量小的排名方式。

解釋 method='min' 的作用

假設 example.xlsx 中的訂單資料化簡如下:

order_id order_amount
10001 5000
10002 8000
10003 5000
10004 3000

如果使用 rank(method='min', ascending=False),這會按照訂單金額由高到低進行排名。如果兩個訂單的總金額相同,會取相同金額中最小的排名分配給這些訂單。例如:

import pandas as pd

# 讀取訂單資料
df = pd.read_excel("example.xlsx")

df = pd.DataFrame(data)

# 使用 method='min' 進行排名
df['order_rank'] = df['order_amount'].rank(ascending=False, method='min')

print(df[['order_id', 'order_amount', 'order_rank']])

程式輸出結果如下:

order_id order_amount order_rank
10001 5000 2
10002 8000 1
10003 5000 2
10004 3000 4

在這個例子中,order_id 為 10001 和 10003 的訂單總金額相同 (5000),所以它們都得到相同的排名 2。如果 method 的值不是 'min',可能會得到不同的排名結果。


其他的 method 參數值

其他常見的 method 參數值如下:

  • max:將相同的值分配最大的排名。例如,如果兩個數值相同,它們將共享最大的排名。
  • average:將相同的值分配平均排名。例如,兩個相同的值將被分配到兩者排名的平均值。
  • first:有相同值時,按出現順序進行排名,先出現的會獲得較小的排名。
  • dense:和 min 類似,但不會跳過後續的排名。例如,有三個相同的值同時獲得排名 1,下一個不同的值將獲得排名 2。

以下用程式碼說明 method 不同參數值的差異:

import pandas as pd

# 讀取訂單資料
df = pd.read_excel("example.xlsx")

df = pd.DataFrame(data)

# 使用不同 method 值進行排名
df['order_rank_min'] = df['order_amount'].rank(ascending=False, method='min')
df['order_rank_max'] = df['order_amount'].rank(ascending=False, method='max')
df['order_rank_avg'] = df['order_amount'].rank(ascending=False, method='average')
df['order_rank_first'] = df['order_amount'].rank(ascending=False, method='first')
df['order_rank_dense'] = df['order_amount'].rank(ascending=False, method='dense')

print(df[['order_id', 'order_amount', 'order_rank', 'order_rank_max', 'order_rank_avg', 'order_rank_first', 'order_rank_dense']])

程式輸出結果如下:

order_id order_amount order_rank_min order_rank_max order_rank_avg order_rank_first order_rank_dense
10001 5000 2 3 2.5 2 2
10002 8000 1 1 1.0 1 1
10003 5000 2 3 2.5 3 2
10004 3000 4 4 4.0 4 3

總結

  • pandas 的 rank 方法能夠根據不同需求設置升序或降序排名。
  • rank 方法的 method 參數允許使用者定義當出現相同值時的排名方式,例如 min 表示給予相同值分配最小排名。

本篇文章同步發布於 Python pandas 使用 rank 得到排名【Python 處理 Excel #16】


上一篇
使用 Python pandas 的 groupby 實現類似 Excel 樞紐分析的功能【Python 處理 Excel #15】
下一篇
Python 將 pandas 的 DataFrame 輸出到 Excel 檔案【Python 處理 Excel #17】
系列文
30 天學會用 Python pandas 和 openpyxl 處理 Excel —— 成為用 Python 處理 Excel 檔案的高手27
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言