iT邦幫忙

2025 iThome 鐵人賽

DAY 13
0

groupby講得有點膩了,忍忍,最後一天。
groupby常用的方法有四個agg(), filter(), transform(), apply()
今天要來到最後一個apply了。

apply的功能是把所有分組內容丟到function或lambda裡去跑,再把回傳的東西拼接來。

  • func(group) 回傳 標量 → 最後輸出 Series(index 是 group key)。
  • func(group) 回傳 Series → 最後輸出 DataFrame(columns 來自 Series 的 index)。
  • func(group) 回傳 DataFrame → 最後輸出 DataFrame(多組 DataFrame 上下拼接)。

不同於前三個方法都有些限制

  • agg 需要每組回傳一個純量值 (如果是一個聚合函數的話)
  • filter 需要每組回傳是否滿足condition,回傳true or false
  • transform 需要回傳列數相同的series或dataframe

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

上一篇
Day11: GroupBy | Filter | transform
系列文
從零開始Pandas-外加一點Matplotlib13
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言