pandas の agg で複数の集計を一度に行う

groupby で集計するとき、sum や mean だけでなく複数の統計量を同時に計算したい場面があります。pandas の agg メソッドを使えば、1 回の呼び出しで複数の集計関数を適用できます。

基本的な使い方

agg に関数名の文字列を渡すと、その集計関数が適用されます。

import pandas as pd

df = pd.DataFrame({
    "category": ["A", "A", "B", "B", "B"],
    "price": [100, 200, 150, 300, 250],
    "quantity": [3, 1, 4, 2, 5]
})

result = df.groupby("category").agg("sum")
print(result)

これだけなら groupby(“category”).sum() と同じですが、agg の真価はここからです。

複数の集計関数を同時に適用する

リストで関数名を渡せば、各列に対して複数の集計を一度に実行できます。

result = df.groupby("category")["price"].agg(["mean", "std", "min", "max"])
print(result)

結果は MultiIndex のカラムを持つ DataFrame になり、平均・標準偏差・最小値・最大値が一覧で得られます。

列ごとに異なる集計を指定する

辞書を使えば、列ごとに適用する関数を変えられます。

result = df.groupby("category").agg({
    "price": ["mean", "max"],
    "quantity": "sum"
})
print(result)

price には平均と最大値、quantity には合計を適用するといった柔軟な指定が可能です。レポート用のサマリーテーブルを一発で生成できるのが便利なところでしょう。

named aggregation で列名を指定する

結果の列名をわかりやすくしたい場合は、named aggregation という構文が使えます。

result = df.groupby("category").agg(
    avg_price=("price", "mean"),
    max_price=("price", "max"),
    total_qty=("quantity", "sum")
)
print(result)
辞書形式の agg

列ごとに関数を柔軟に指定できるが、結果が MultiIndex カラムになりやすい

named aggregation

出力列名を直接指定でき、フラットなカラム構造になる

named aggregation では (列名, 集計関数) のタプルをキーワード引数として渡します。MultiIndex にならないため、結果をそのまま使いやすいのが利点です。

カスタム関数を使う

組み込みの関数だけでは足りない場合は、自作の関数を渡すこともできます。

def price_range(x):
    return x.max() - x.min()

result = df.groupby("category").agg(
    avg_price=("price", "mean"),
    range_price=("price", price_range)
)
print(result)

ラムダ式でも書けますが、named aggregation の中ではラムダ式が使えないケースがあるため、名前付き関数を定義しておくほうが安全です。

groupby なしでも使える

agg は groupby と組み合わせるのが一般的ですが、DataFrame や Series に直接呼び出すこともできます。

stats = df["price"].agg(["mean", "std", "median"])
print(stats)

特定の列の統計量を手早くまとめたいときに便利な書き方です。describe よりも自分で集計関数を選びたいときに使い分けるとよいでしょう。