groupby講得有點膩了,忍忍,最後一天。
groupby常用的方法有四個agg(), filter(), transform(), apply()
今天要來到最後一個apply了。
apply的功能是把所有分組內容丟到function或lambda裡去跑,再把回傳的東西拼接來。
不同於前三個方法都有些限制
apply沒有,超級靈活,想怎麼長就怎麼長,隨user需求野蠻生長。它的語法和前三個很像很好上手。df.groupby(group column).apply(apply_func)
以下面程式為例,
def apply_func(g):
return pd.DataFrame({
"交易量總和": [g["交易量_公斤"].sum()],
"交易量平均": [g["交易量_公斤"].mean()],
"交易量最大": [g["交易量_公斤"].max()],
"交易量最小": [g["交易量_公斤"].min()],
})
result = df.groupby("市場代號").apply(apply_func)
#Result
交易量總和 交易量平均 交易量最大 交易量最小 市場代號
104 0 0 0 0 0
109 0 0 0 0 0
220 0 0 0 0 0
241 0 0 0 0 0
260 0 0 0 0 0
338 0 0 0 0 0
400 0 0 0 0 0
420 0 96178 1023 8100 12
423 0 0 0 0 0
512 0 0 0 0 0
800 0 237575 1439 13292 10
900 0 0 0 0 0
950 0 25234 494 2308 3
它非常彈性,適合處理一些難纏的需求,但是要小心,靈活的背後犧牲了效率,所以也是不要為apply而apply啊!
原則就是能用agg()和transform()處理的就不要用apply
然後下面來做個小小demo,看一下四個方法的差異。
原始資料 df
dept | name | sales |
---|---|---|
A | Tom | 100 |
A | Amy | 120 |
B | John | 90 |
B | Ann | 110 |
C | May | 70 |
Step 1. Split
依照 dept 分組 → 得到 3 個 group (A, B, C)
Step 2. Apply → 根據方法不同,有不同處理邏輯
────────────────────────────────────
① agg (壓縮成統計值)
每組 → 1 個或多個統計數
Combine → 回傳 DataFrame/Series(行數 ↓)
輸出:
dept | mean |
---|---|
A | 110.0 |
B | 100.0 |
C | 70.0 |
────────────────────────────────────
② transform (計算後回填)
每組 → 計算值廣播回組內每一列
Combine → 保持原始行數(行數 = 原始)
輸出:
dept | sales | demean |
---|---|---|
A | 100 | -10.0 |
A | 120 | +10.0 |
B | 90 | -10.0 |
B | 110 | +10.0 |
C | 70 | 0.0 |
────────────────────────────────────
③ filter (整組保留/剔除)
每組 → True/False → 保留或丟掉整組
Combine → 回傳子集(行數 ↓)
輸出:(假設條件 = 平均 > 90)
dept | name | sales |
---|---|---|
A | Tom | 100 |
A | Amy | 120 |
B | John | 90 |
B | Ann | 110 |
────────────────────────────────────
④ apply (萬用牌)
每組 → 丟進自訂函數 → 結果可任意形狀
Combine → 自動拼接
Combine 後行數可多可少
輸出:(每組取前 1 名)
dept | name | sales |
---|---|---|
A | Amy | 120 |
B | Ann | 110 |
C | May | 70 |