快轉到主要內容
  1. Posts/

用 groupby / pivot_table 做出整齊的統計表格

·2 分鐘
Data Data Basics Data Pandas
目錄

在數據分析中,我們經常會希望整理出一個分組後的統計表格。 例如:假設我們有一份學生考試成績的資料表格,我們可能會想知道「每個班級的平均成績」是多少。

data = {
    '班級': ['A', 'A', 'B', 'B', 'B', 'C', 'C'],
    '姓名': ['小明', '小美', '小華', '小強', '小美', '小安', '小傑'],
    '性別': ['男', '女', '男', '男', '女', '女', '男'],
    '成績': [85, 90, 78, 82, 88, 95, 91],
    '缺席次數': [2, 0, 3, 1, 0, 0, 2]
}

df = pd.DataFrame(data)

結果呈現如下:

班級  姓名 性別  成績  缺席次數
0  A  小明  男  85     2
1  A  小美  女  90     0
2  B  小華  男  78     3
3  B  小強  男  82     1
4  B  小美  女  88     0
5  C  小安  女  95     0
6  C  小傑  男  91     2

這時候,就需要將資料依照「班級」進行分組,再計算「成績」的平均值。 這類分組與彙總的操作,就可以透過 pandas 的 groupbypivot_table 來實現。

group_by
#

基本語法
#

df.groupby("col_name") 會根據 col_name 把大家分組,例如,col_name班級的話,上述的表的內容就會依據班級而被分為三組(A、B、C)。由於運行之後得到的是類似三張表格的東西,所以他不是一個有效的表格數據,不能直接用 print 呈現出來。如果想要能夠看到相關的數值,我們需要先提取我們關注的其他 column,再使用“聚合函數”,例如 mean, sum. 例如:我們在乎的是每個班級的平均成績,

df.groupby("班級")["成績"].mean()

我們就能得到結果:

班級
A    87.500000
B    82.666667
C    93.000000
Name: 成績, dtype: float64

如果我們不只是在乎成績,還在乎班級的缺席次數我們可以把 list 傳入方括中:

df.groupby("班級")[["成績","缺席次數"]].mean()

就能得到下面一張表格:

成績 缺席次數
班級
A 87.500000 1.000000
B 82.666667 1.333333
C 93.000000 1.000000

我們還可以根據班級+性別來進行分組計算平均成績和缺席次數:

df.groupby(["班級", "性別"])[["成績","缺席次數"]].mean()
成績 缺席次數
班級 性別
A 90.0 0.0
85.0 2.0
B 88.0 0.0
80.0 2.0
C 95.0 0.0
91.0 2.0

一次使用多個聚合函數
#

如果我們不只是想知道平均成績,還想知道加總成績,我們可以使用 agg,它可以一次性讓我們知道多個聚合函數的結果:

df.groupby("班級")["成績"].agg(['mean', 'sum'])

就能得到:

mean sum
班級
A 87.500000 175
B 82.666667 248
C 93.000000 186

自定義聚合函數
#

再來我們還可以自己定義聚合函數,這很簡單,只需要自己定義好函數後,使用 apply. 例如:

df.groupby("班級")["成績"].apply(function)

pivot_table
#

雖然 groupby 非常強大,但在一些資料展示與整理的情境中,使用 pivot_table 可以更快速地產出「表格式」的總結結果。和 groupby 一樣,pivot_table 也可以做分組彙總,不同的是,它會自動幫你整理成橫向與縱向都有對齊的表格格式,非常適合做報表。

基本語法
#

pd.pivot_table(df, index="班級", values="成績", aggfunc="mean")
成績
班級
A 87.500000
B 82.666667
C 93.000000

也可以一次計算多個欄位的平均值:

pd.pivot_table(df, index="班級", values=["成績", "缺席次數"], aggfunc="mean")

加上 columns:分群之後再分類
#

如果你希望能看出「每個班級中,男生與女生的成績平均」呢?這時候就可以加上 columns="性別"

pd.pivot_table(df, index="班級",values="成績", columns="性別", aggfunc="mean")
性別
班級
A 90.0 85.0
B 88.0 80.0
C 95.0 91.0

同時搭配多個值欄位 + 多個 columns
#

最後,如果我們想一次看到「每個班級、每個性別」的平均「成績」與「缺席次數」,就可以這樣寫:

pd.pivot_table(
    df,
    values=["成績", "缺席次數"],
    index="班級",
    columns="性別",
    aggfunc="mean"
)

就能得到:

成績 缺席次數
性別
班級
A 90.0 85.0 0.0 2.0
B 88.0 80.0 0.0 2.0
C 95.0 91.0 0.0 2.0

相關文章

用 `get_dummies` 將分類變數轉換為數值型資料
·1 分鐘
Data Data Basics Data Pandas
用query進行條件篩選
·1 分鐘
Data Data Basics Data Pandas
用 cut 對數據分組
·1 分鐘
Data Data Basics Data Pandas