2026年11月2日 星期一

【PySpark 大數據處理 08】數據樞紐分析:群組運算 (GroupBy) 與多維度聚合 (Aggregation)

歷經了前幾篇的資料清洗(處理 Null、去除重複、字串與時間正規化),我們的資料終於變得乾淨且具備標準結構了!接下來,我們將進入大數據分析中最讓人興奮的階段:萃取商業價值。

無論是計算「每個月的總營收」、「各個分店的平均客單價」,還是「不同感測器的最高溫度」,背後的核心技術都離不開「群組運算 (GroupBy)」與「聚合函數 (Aggregation)」。這就像是在 PySpark 裡執行超高效率的 Excel 樞紐分析表!

1. 核心觀念:Split - Apply - Combine

在學習語法前,我們必須先理解群組運算在底層是如何運作的。在資料科學界,這被稱為 Split-Apply-Combine (拆分-應用-結合) 策略:

GroupBy 運算原理:Split - Apply - Combine 1. 原始資料表 類別 數值 A 10 B 20 A 30 B 10 Split 2. 分組 (GroupBy) A 10 A 30 B 20 B 10 Apply Apply 3. 聚合 (Sum) 10+30 20+10 Combine 4. 最終報表 類別 總和 A 40 B 30
▲ 群組運算 (Split-Apply-Combine) 流程拆解圖

首先,Spark 會根據你指定的欄位(如:商品類別)將資料拆分 (Split) 成多個小群組;接著對每個小群組應用 (Apply) 計算函數(如:加總、平均);最後再將這些計算結果結合 (Combine) 成一張全新的統計報表。

2. 基礎群組運算:單一維度與單一聚合

讓我們先從最簡單的情境開始:計算每個「商品類別 (Category)」的資料筆數,以及總銷售額。

# 1. 計算每個類別有幾筆資料 (常被用來觀察資料分佈)
df_count = df.groupBy("Category").count()
df_count.show()

# 2. 計算每個類別的總銷售額 (Price 欄位的加總)
# 注意:使用 sum, avg 等函數前,必須從 pyspark.sql.functions 匯入
import pyspark.sql.functions as F

df_sum = df.groupBy("Category").sum("Price")
df_sum.show()

3. 進階火力展示:多維度分組與多重聚合 (agg)

在真實的企業報表中,老闆往往要求更複雜的指標,例如:「列出每年、每個月的總營收、平均客單價,以及最高單筆消費」。這時候我們需要使用強大的 agg() (Aggregation) 函數,搭配 alias() 來為產出的新欄位重新命名。

# 多維度 GroupBy:同時依照年份與月份分組
df_report = df.groupBy("Year", "Month").agg(
    
    # 總營收 (加總)
    F.sum("Price").alias("Total_Revenue"),
    
    # 平均客單價 (平均值,並四捨五入到小數點後兩位)
    F.round(F.avg("Price"), 2).alias("Avg_Order_Value"),
    
    # 最高消費金額 (最大值)
    F.max("Price").alias("Max_Transaction")
    
# 最後,我們可以使用 orderBy 將報表依照年份與月份進行排序
).orderBy("Year", "Month")

df_report.show()

這段程式碼的寫法非常優雅且結構化,是不是已經感受到資料工程師的浪漫了呢?

4. 課後小結

透過 `groupBy()` 與 `agg()`,我們成功將海量的原始資料,濃縮成了具備商業價值的統計報表。但在目前的寫法中,我們大量依賴了 DataFrame 專屬的 API(如 `col()`, `agg()`)。如果你是一位非常熟悉標準關聯式資料庫(如 MySQL 或 SQL Server)的開發者,難道就不能直接寫 SQL 嗎?

答案是:絕對可以!下一篇文章,我們將教大家如何突破 API 語法的限制,將 PySpark DataFrame 註冊為暫存表,無縫整合標準 SQL 查詢,發揮你原有的資料庫硬實力!

沒有留言:

張貼留言

熱門文章