Pandas 聚合函數
聚合(Aggregation)是將多個值計算成單一值的操作,例如計算總和、平均值等。Pandas 的 agg() 方法提供了靈活的聚合功能。
基本聚合
對 Series 聚合
import pandas as pd
s = pd.Series([1, 2, 3, 4, 5])
# 單一聚合
print(s.sum()) # 15
print(s.mean()) # 3.0
# 多種聚合
print(s.agg(['sum', 'mean', 'std']))
sum 15.000000
mean 3.000000
std 1.581139
dtype: float64
對 DataFrame 聚合
df = pd.DataFrame({
'A': [1, 2, 3],
'B': [4, 5, 6],
'C': [7, 8, 9]
})
# 對所有欄位聚合
print(df.agg('sum'))
A 6
B 15
C 24
dtype: int64
agg() 的多種用法
對所有欄位套用多種函數
result = df.agg(['sum', 'mean', 'max'])
print(result)
A B C
sum 6.0 15.0 24.0
mean 2.0 5.0 8.0
max 3.0 6.0 9.0
對不同欄位套用不同函數
result = df.agg({
'A': 'sum',
'B': 'mean',
'C': ['min', 'max']
})
print(result)
A B C
sum 6.0 NaN NaN
mean NaN 5.0 NaN
min NaN NaN 7.0
max NaN NaN 9.0
使用命名聚合(Named Aggregation)
搭配 groupby 使用時,可以自訂結果欄位名稱:
df = pd.DataFrame({
'city': ['Taipei', 'Tokyo', 'Taipei', 'Tokyo'],
'sales': [100, 200, 150, 250],
'profit': [10, 20, 15, 25]
})
result = df.groupby('city').agg(
total_sales=('sales', 'sum'),
avg_sales=('sales', 'mean'),
max_profit=('profit', 'max')
)
print(result)
total_sales avg_sales max_profit
city
Taipei 250 125.0 15
Tokyo 450 225.0 25
自訂聚合函數
使用 lambda
# 計算範圍(最大 - 最小)
result = df.groupby('city')['sales'].agg(lambda x: x.max() - x.min())
使用自訂函數
def custom_agg(x):
return x.sum() / x.count() # 等同於 mean
result = df.groupby('city')['sales'].agg(custom_agg)
同時使用內建和自訂函數
def range_func(x):
return x.max() - x.min()
result = df.groupby('city')['sales'].agg(['sum', 'mean', range_func])
常用聚合函數列表
| 函數 | 說明 |
|---|---|
sum | 總和 |
mean | 平均值 |
median | 中位數 |
min | 最小值 |
max | 最大值 |
count | 非空值數量 |
size | 總數量(含空值) |
std | 標準差 |
var | 變異數 |
first | 第一個值 |
last | 最後一個值 |
nunique | 不重複值數量 |
prod | 乘積 |
搭配 GroupBy 使用
df = pd.DataFrame({
'category': ['A', 'A', 'B', 'B', 'B'],
'value1': [10, 20, 30, 40, 50],
'value2': [1, 2, 3, 4, 5]
})
# 完整的聚合範例
result = df.groupby('category').agg({
'value1': ['sum', 'mean', 'count'],
'value2': ['min', 'max']
})
print(result)
value1 value2
sum mean count min max
category
A 30 15.0 2 1 2
B 120 40.0 3 3 5
展平多層欄位名稱
result = df.groupby('category').agg({
'value1': ['sum', 'mean'],
'value2': ['min', 'max']
})
# 展平欄位名稱
result.columns = ['_'.join(col) for col in result.columns]
print(result.columns)
# Index(['value1_sum', 'value1_mean', 'value2_min', 'value2_max'], dtype='object')
describe():快速統計
describe() 是一種特殊的聚合,一次產生多種統計值:
result = df.groupby('category')['value1'].describe()
print(result)
count mean std min 25% 50% 75% max
category
A 2.0 15.0 7.07 10.0 12.5 15.0 17.5 20.0
B 3.0 40.0 10.00 30.0 35.0 40.0 45.0 50.0
百分位數聚合
# 計算特定百分位數
result = df.groupby('category')['value1'].agg(
lambda x: x.quantile(0.9)
)
# 多個百分位數
result = df.groupby('category')['value1'].agg([
('p25', lambda x: x.quantile(0.25)),
('p50', lambda x: x.quantile(0.50)),
('p75', lambda x: x.quantile(0.75))
])
實際應用
銷售報表
df = pd.DataFrame({
'store': ['A', 'A', 'B', 'B', 'A'],
'product': ['X', 'Y', 'X', 'Y', 'X'],
'sales': [100, 150, 200, 180, 120],
'quantity': [10, 15, 20, 18, 12]
})
report = df.groupby('store').agg(
total_sales=('sales', 'sum'),
avg_sales=('sales', 'mean'),
total_quantity=('quantity', 'sum'),
product_count=('product', 'nunique')
)
print(report)
統計摘要
summary = df.groupby('store').agg({
'sales': ['sum', 'mean', 'std', 'min', 'max'],
'quantity': ['sum', 'mean']
}).round(2)