HOWTO · Pandas

Pandas 由兩列來 groupby

本教程講解了我們如何在 Pandas 中將 DataFrame.groupby()方法應用於兩列,以將 DataFrame 分成幾組。

本頁內容

若要依兩個欄位將資料列分組,請將欄位名稱組成清單,傳給 DataFrame.groupby()。每一組不同的欄位值組合都會形成一個群組。以下範例使用同一個含六列的 DataFrame,示範如何檢視群組、計算各組的資料列數,以及找出每種就業狀態下最大的子群組。請在已安裝 pandas 的環境中執行;此處不宣稱有執行結果。

依兩個欄位將 DataFrame 分組

清單 ['Gender', 'Employed'] 會告訴 pandas 同時依這兩個欄位分組。例如,只有兩個值都相符時,某列才會歸入 Female/Yes 群組。完整程式可獨立執行,後續各步驟也都能沿用同一份資料。

本節中的程式碼以及顯示的標籤或輸出仍為英文。

import pandas as pd

data = pd.DataFrame(
    {
        "Name": ["Jennifer", "Travis", "Bob", "Emma", "Luna", "Anish"],
        "Gender": ["Female", "Male", "Male", "Female", "Female", "Male"],
        "Employed": ["Yes", "No", "Yes", "No", "Yes", "No"],
        "Age": [30, 28, 27, 24, 28, 25],
    }
)

groups = data.groupby(["Gender", "Employed"])

print("Groups:")
for group_key, group_rows in groups:
    print(f"{group_key}: {len(group_rows)} rows")

counts = groups.size().reset_index(name="Count")
print("\nRows per pair:")
print(counts.to_string(index=False))

largest = groups.size().groupby(level="Employed").max()
print("\nLargest subgroup per employment value:")
print(largest.to_string())

逐一走訪分組結果

走訪 groups 時,每個實際存在的組合都會產生一組 (group_key, group_rows)。在此,group_key 依序包含 Gender 和 Employed 的值;group_rows 則是包含相符來源資料列的 DataFrame。可直接使用走訪時取得的 DataFrame;再用 get_group() 取一次會重複查找。pandas 預設會排序群組鍵,而不是保留各群組在輸入資料中的出現順序;不過,每個群組內的資料列仍會維持原本的相對順序。範例中的英文輸出標籤是 Groups:。

計算每個群組的列數

groups.size() 會傳回每個欄位值組合群組的資料列數。呼叫 reset_index(name="Count") 會將兩個分組索引層級及其計數轉成一般欄位,方便顯示或供後續操作使用。即使非分組欄位(例如 Age)含有缺失值,size() 仍會計算該列;若改為計算特定欄位,則只會計算其中非空的值,結果可能不同。因此,Count 欄代表每個 Gender/Employed 組合的資料列數,而不是填妥的姓名或年齡數量。範例中的英文輸出標籤是 Rows per pair:。

找出每個欄位值所對應的最大群組

最後的運算式先取得各欄位值組合的計數,再依該 Series 的 Employed 索引層級分組,並套用 max()。結果是每種就業狀態下最大的 Gender 子群組列數。在這份資料中,Female/Yes 和 Male/No 群組各有兩列,因此兩種就業狀態的最大子群組都是兩列。這裡取的是子群組計數的最大值;它不會選出底層資料列,也不會指出哪個 Gender 取得最大值。max() 方法另有說明。