進行資料分析時,前幾名的資料總是讓人特別感興趣,這篇文章介紹如何使用 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']])
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']])
groupby()
根據 customer_name
對訂單數量進行分組,並計算每位客戶的總訂單數量。reset_index()
則將分組結果轉換回 DataFrame。rank()
根據總訂單數量進行排名,採用從數量大到數量小的排名方式。假設 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
參數值如下:
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 |
rank
方法能夠根據不同需求設置升序或降序排名。rank
方法的 method
參數允許使用者定義當出現相同值時的排名方式,例如 min
表示給予相同值分配最小排名。