閉じる

Pandas groupbyの基本から応用まで:データ集計の実践的な書き方

Pandasのgroupbyは、データを特定のカテゴリごとに分類するための強力なツールです。

この機能は、SQLのGROUP BY句と似た役割を果たしますが、Pythonの柔軟性を活かした高度な操作が可能です。

データ分析の実務においては、平均値の算出や合計値の集計など、グループ単位での処理が不可欠な場面が数多く存在します。

本記事では、初心者の方が最初につまずきやすい基本概念から、現場で即戦力となる応用テクニックまでを詳しく解説していきます。

この記事を読み終える頃には、複雑なデータセットを自在に集計し、ビジネスに役立つインサイトを抽出できるようになるでしょう。

Pandas groupbyの基本:Split-Apply-Combineの仕組み

Pandasのgroupbyを理解する上で最も重要な概念は、Split(分割)Apply(適用)Combine(結合)という3つのステップです。

まず、指定したキーに基づいてデータフレームが小さなグループに分割されます。

次に、各グループに対して合計や平均、独自の関数などの処理が適用されます。

最後に、それらの結果が再び一つのデータ構造にまとめられるという流れで処理が進行します。

この仕組みを理解しておくことで、なぜ特定のコードを書く必要があるのかが論理的に把握できるようになります。

まずは、簡単なサンプルデータを用いて基本的な使い方を見ていきましょう。

Python
import pandas as pd

# サンプルデータの作成
data = {
    '部署': ['営業', '営業', '技術', '技術', '総務', '営業'],
    '氏名': ['田中', '佐藤', '鈴木', '高橋', '伊藤', '渡辺'],
    '売上': [100, 150, 200, 180, 90, 120],
    '経費': [30, 45, 50, 40, 20, 35]
}
df = pd.DataFrame(data)

# 部署ごとにグループ化し、売上の合計を算出する
result = df.groupby('部署')['売上'].sum()

print(result)
実行結果
部署
営業    370
技術    380
総務     90
Name: 売上, dtype: int64

上記のコードでは、groupby('部署')によって部署ごとにデータを分割しています。

その後に続く['売上'].sum()によって、各部署の売上合計が計算され、最終的な結果として表示されています。

このように、「どの列でグループ化するか」と「どの列にどの処理をするか」をセットで記述するのが基本形です。

複数の集計を一度に行うaggメソッドの活用

実務では、一つのグループに対して「合計」と「平均」を同時に知りたいケースが多々あります。

そのような場合に便利なのが、agg(aggregation)メソッドです。

aggメソッドを使用すると、複数の集計関数を一度に適用したり、列ごとに異なる集計を指定したりすることができます。

単一の列に複数の関数を適用する

特定の列に対して、平均、最大値、最小値をまとめて算出する方法を確認しましょう。

Python
# 部署ごとの売上の平均・最大・最小を算出
summary = df.groupby('部署')['売上'].agg(['mean', 'max', 'min'])

print(summary)
実行結果
      mean  max  min
部署                
営業  123.33  150  100
技術  190.00  200  180
総務   90.00   90   90

リスト形式で関数名を渡すだけで、自動的にカラム名が関数名になった表が作成されます。

これにより、データの特徴を多角的に分析することが容易になります。

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

「売上は合計したいが、経費は平均を知りたい」といった場合には、辞書形式を利用します。

Python
# 辞書形式で列ごとに集計内容を指定
custom_agg = df.groupby('部署').agg({
    '売上': 'sum',
    '経費': 'mean'
})

print(custom_agg)
実行結果
    売上    経費
部署          
営業  370  36.67
技術  380  45.00
総務   90  20.00

このように、列名と関数名を対応させた辞書を渡す手法は、現場で最も多用される記述法の一つです。

transformメソッドによるデータの加工

集計結果を元のデータフレームと同じサイズで取得したい場合には、transformメソッドが非常に有効です。

通常のgroupbyでは行数がグループ数に集約されてしまいますが、transformは元の行数を維持します。

例えば、「各個人の売上が、その部署の平均売上と比べてどれくらい乖離しているか」を計算したい時に役立ちます。

Python
# 部署ごとの平均売上を各行に割り当てる
df['部署平均'] = df.groupby('部署')['売上'].transform('mean')

# 平均との差分を計算
df['平均との差'] = df['売上'] - df['部署平均']

print(df)
実行結果
   部署  氏名   売上  経費        部署平均      平均との差
0  営業  田中  100  30  123.333333 -23.333333
1  営業  佐藤  150  45  123.333333  26.666667
2  技術  鈴木  200  50  190.000000  10.000000
3  技術  高橋  180  40  190.000000 -10.000000
4  総務  伊藤   90  20   90.000000   0.000000
5  営業  渡辺  120  35  123.333333  -3.333333

このように、元のデータフレームに統計量をマージする手間を省けるのがtransformの大きなメリットです。

欠損値をグループごとの平均値で埋めるといった処理にも頻繁に使用されます。

filterメソッドによるグループの絞り込み

特定の条件を満たすグループのみを抽出したい場合は、filterメソッドを使用します。

個別の行ではなく、「グループ全体の集計結果」を基準にフィルタリングできるのが特徴です。

Python
# 売上の合計が300以上の部署のみを抽出する
filtered_df = df.groupby('部署').filter(lambda x: x['売上'].sum() >= 300)

print(filtered_df)
実行結果
   部署  氏名   売上  経費
0  営業  田中  100  30
1  営業  佐藤  150  45
2  技術  鈴木  200  50
3  技術  高橋  180  40
5  営業  渡辺  120  35

この例では、売上合計が90しかない「総務」のデータが、結果から除外されています。

特定の規模以上のグループだけを分析対象としたい場合に、非常に便利な手法です。

複数キーによるグループ化とインデックスの扱い

実務では、「年」と「月」や、「部署」と「役職」など、複数の項目を組み合わせてグループ化することが一般的です。

その場合は、groupbyの引数にリスト形式で列名を渡します。

Python
# 複数の列をキーにしてグループ化
multi_result = df.groupby(['部署', '氏名']).sum()

print(multi_result)

複数のキーを指定すると、結果は「マルチインデックス」と呼ばれる多層構造のインデックスになります。

しかし、その後の処理でマルチインデックスが扱いづらいと感じることも多いでしょう。

そのような場合は、as_index=Falseを指定することで、集計キーを通常の列として保持することが可能です。

Python
# indexにせず、通常のデータフレーム形式で取得
result_df = df.groupby('部署', as_index=False)['売上'].sum()

print(result_df)
実行結果
   部署   売上
0  営業  370
1  技術  380
2  総務   90

この書き方をしておくと、後続のグラフ作成やCSV出力がスムーズに行えるため、推奨されるテクニックの一つです。

効率的な時系列データのグループ化

Pandasのgroupbyは、時系列データの集計にも威力を発揮します。

日付データを持つ列がある場合、dtアクセサやpd.Grouperを組み合わせることで、月ごとや四半期ごとの集計が容易になります。

Python
# 日付データを含むサンプルの作成
df['日付'] = pd.to_datetime(['2026-01-10', '2026-01-15', '2026-02-10', '2026-02-20', '2026-03-05', '2026-03-25'])

# 月ごとにグループ化して売上を集計
monthly_sales = df.groupby(df['日付'].dt.month)['売上'].sum()

print(monthly_sales)
実行結果
日付
1    250
2    380
3    210
Name: 売上, dtype: int64

このように、dt.monthを利用することで、日付列から直接「月」の情報を抽出してグループ化に利用できます。

より高度なリサンプリングが必要な場合は、resampleメソッドも検討すると良いでしょう。

groupbyを使いこなすための注意点

groupbyを使用する際、メモリ使用量や計算速度に注意が必要な場合があります。

非常に大きなデータセットに対してgroupbyを実行すると、一時的に多くのメモリを消費することがあります。

事前に不要な列を削除しておいたり、カテゴリ型のデータ(Categorical型)を利用したりすることで、パフォーマンスを改善できる場合があります。

また、集計対象に数値以外の列が含まれている場合、Pandasのバージョンによってはエラーが発生したり、自動的に除外されたりすることがあります。

常に数値列を明示的に選択して集計を行う習慣をつけておくと、トラブルを未然に防ぐことができます。

まとめ

Pandasのgroupbyは、単なる集計機能を超えた、データ分析の核となるメソッドです。

基本的な合計や平均の算出から、aggによる一括集計、transformによる値の展開、そしてfilterによる抽出まで、その活用範囲は非常に多岐にわたります。

これらの機能を組み合わせることで、複雑な条件での分析もシンプルなコードで記述できるようになります。

まずは今回紹介した基本的なパターンを手元のデータで試し、徐々に応用的な使い方に慣れていってください。

Pandasを自由に使いこなすことができれば、あなたのデータ分析業務の効率は飛躍的に向上するはずです。

URLをコピーしました!