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)