はじめに
pandasの groupby() は、カテゴリごとの集計処理に欠かせない関数です。
「性別ごとに平均を出したい」「学年ごとに最大点数と最小点数を同時に知りたい」など、実務でもっともよく使われるデータ分析手法の一つです。
この記事では、基本的な groupby の使い方から、複数列・複数集計関数の応用パターンまでを、丁寧に図解・コード付きで解説します。
1. 基本のgroupby + 単一関数
▶ 例:性別ごとの平均点を出す
df.groupby("性別")["点数"].mean()| 性別 | 点数 |
|---|---|
| 女 | 81.0 |
| 男 | 88.67 |
groupby("カテゴリ列")[集計対象].関数()mean()以外にもsum(),max(),min(),count()などがあります
2. groupby + 複数列の集計
▶ 例:性別ごとに「点数」「年齢」の平均を同時に計算
df.groupby("性別")[["点数", "年齢"]].mean()結果:
| 性別 | 点数 | 年齢 |
|---|---|---|
| 女 | 81.0 | 21.5 |
| 男 | 88.67 | 19.5 |
✅ カテゴリごとに「複数の列」を同時に集計したいときは、列名をリストで指定します。
3. groupby + 複数の集計関数(agg)
▶ 例:性別ごとに「平均」「最大」「最小」を出す
df.groupby("性別")["点数"].agg(["mean", "max", "min"])結果:
| 性別 | mean | max | min |
|---|---|---|---|
| 女 | 81.0 | 92 | 70 |
| 男 | 88.67 | 95 | 83 |
agg()を使えば、複数の統計関数を一括で適用できます
4. 複数列 × 複数関数(ネスト構造)
▶ 例:性別ごとに「点数→平均・最大」、「年齢→平均・件数」
df.groupby("性別").agg({
"点数": ["mean", "max"],
"年齢": ["mean", "count"]
})
結果(MultiIndex):
点数 年齢
mean max mean count
性別
女 81.0 92 21.5 2
男 88.67 95 19.5 2
✅ 複数の列ごとに、異なる関数を割り当てたいときは辞書形式で書きます。
5. 集計結果の列名を見やすく変える方法
MultiIndexで出てきた列名を、シンプルに1階層に変換したいとき:
grouped = df.groupby("性別").agg({
"点数": ["mean", "max"],
"年齢": ["mean", "count"]
})
# 列名を「列名_集計関数」の形式にフラット化
grouped.columns = ['_'.join(col) for col in grouped.columns]
grouped.reset_index(inplace=True)結果:
| 性別 | 点数_mean | 点数_max | 年齢_mean | 年齢_count |
|---|---|---|---|---|
| 女 | 81.0 | 92 | 21.5 | 2 |
| 男 | 88.67 | 95 | 19.5 | 2 |
6. groupbyのcount()は「NaNを除外」してカウントする
df.groupby("性別")["年齢"].count()count()は NaNを含まないセル数をカウントします- 欠損を含めた総数を知りたい場合は、
.size()を使うのが正解です
7. 条件付きgroupby(bool列を使った前処理)
点数が80点以上かどうかで合格・不合格を先に作って、グループ化することもできます:
df["合格"] = df["点数"] >= 80
df.groupby("合格")["点数"].mean()| 合格 | 点数 |
|---|---|
| False | 70.0 |
| True | 89.5 |
✅ 条件によって「カテゴリを新しく作ってからgroupby」するのは、実務でも非常によく使われるテクニックです。
✅ よく使う集計関数まとめ
| 関数 | 内容 |
|---|---|
mean() | 平均 |
sum() | 合計 |
max() | 最大値 |
min() | 最小値 |
count() | 欠損値を除く件数 |
size() | 欠損も含めた件数 |
std() | 標準偏差 |
nunique() | ユニークな値の個数 |
✅ まとめ
| 操作 | 使い方 |
|---|---|
| 単純集計 | df.groupby("カテゴリ")["値"].mean() |
| 複数列 | df.groupby("カテゴリ")[["列1", "列2"]].sum() |
| 複数関数 | agg(["mean", "max"]) |
| 列ごとに異なる関数 | agg({"列1": [...], "列2": [...]}) |
| 集計結果の列名整形 | .columns = ['_'.join(col) for col in ...] |

コメント