【Pandas徹底解説】groupby()でデータを集計し統計量を算出する方法
データ分析において、「特定のカテゴリやグループごとにデータを集計し、その統計量(合計、平均、最大値など)を算出したい」というニーズは非常に頻繁に発生します。例えば、性別ごとの平均身長、地域別の売上合計、商品カテゴリごとの最安値などです。Pandasの**groupby()メソッド**は、このようなグループ化と集計処理を非常に強力かつ効率的に行うための核心的な機能です。この記事では、groupby()の基本的な使い方から、様々な統計量の算出方法まで、短いサンプルコードと丁寧な解説を交えてご紹介します。
groupby()とは?なぜデータ集計に不可欠なのか?
groupby()メソッドは、SQLのGROUP BY句のように、DataFrameのデータを1つ以上の列の値に基づいて「グループ化」するための機能です。グループ化されたデータに対して、その後で様々な集計関数(アグリゲーション関数)を適用することで、グループごとの統計量を算出できます。
groupby()がデータ集計に不可欠な理由は以下の通りです。
-
洞察の抽出: データ全体の傾向だけでなく、特定のサブグループがどのような特性を持っているかを明らかにできます。
-
比較分析: 異なるグループ間の特性を比較し、ビジネス上の意思決定や仮説検証に役立てます。
-
データ構造の簡素化: 大規模なデータセットを、より扱いやすい集計結果に変換できます。
-
効率的な処理: 大量のデータに対してループ処理を行うよりも、はるかに高速に集計を実行できます。
groupby()の基本的な使い方
まずは、groupby()メソッドの最も基本的な使い方を見ていきましょう。
1つの列でグルーピングし、合計値を算出する
groupby()にグループ化したい列名を指定し、その後で集計したい列と集計関数(例: sum()) を指定します。
import pandas as pd
# サンプルDataFrameの作成
df = pd.DataFrame({
'支店': ['東京', '大阪', '東京', '名古屋', '大阪'],
'商品': ['A', 'B', 'A', 'C', 'B'],
'売上': [100, 150, 120, 80, 200],
'在庫': [10, 20, 15, 5, 25]
})
print("オリジナルDataFrame:\n", df)
# '支店'ごとに'売上'の合計を算出
sales_by_branch = df.groupby('支店')['売上'].sum()
print("\n支店ごとの売上合計:\n", sales_by_branch)
解説:
-
df.groupby('支店'): DataFrameを’支店’列の値(’東京’, ‘大阪’, ‘名古屋’)に基づいてグループ化します。この時点ではまだ集計は実行されません。 -
['売上']: グループ化されたデータのうち、’売上’列だけを集計対象として選択します。 -
.sum(): 選択された’売上’列に対して、グループごとに合計値を算出します。
結果はSeriesとして返され、インデックスがグループキー(支店名)、値が集計結果となります。
様々な統計量を算出する
groupby()の後に適用できる集計関数はsum()だけではありません。代表的な統計量を見ていきましょう。
平均値 (mean())
グループごとの平均値を算出します。
# '支店'ごとに'売上'の平均値を算出
mean_sales_by_branch = df.groupby('支店')['売上'].mean()
print("\n支店ごとの売上平均:\n", mean_sales_by_branch)
最大値 (max()) と最小値 (min())
グループごとの最大値と最小値を算出します。
# '支店'ごとに'売上'の最大値と最小値を算出
max_sales_by_branch = df.groupby('支店')['売上'].max()
min_sales_by_branch = df.groupby('支店')['売上'].min()
print("\n支店ごとの売上最大値:\n", max_sales_by_branch)
print("\n支店ごとの売上最小値:\n", min_sales_by_branch)
要素数 (count()) とユニークな要素数 (nunique())
グループごとの要素数(NaNを除く)や、ユニークな要素の数を算出します。
import numpy as np
df_nan = pd.DataFrame({
'Category': ['A', 'B', 'A', 'B', 'A'],
'Value': [10, 20, np.nan, 40, 50]
})
# 'Category'ごとの'Value'の要素数を算出 (NaNは含まない)
count_by_category = df_nan.groupby('Category')['Value'].count()
print("\nCategoryごとのValueの要素数:\n", count_by_category)
# '支店'ごとのユニークな'商品'の数を算出
nunique_products_by_branch = df.groupby('支店')['商品'].nunique()
print("\n支店ごとのユニークな商品の数:\n", nunique_products_by_branch)
解説:
-
count()はNaNを除外して要素数をカウントします。 -
nunique()はグループ内のユニークな値の数をカウントします。
複数の列でグルーピングする
複数の列を組み合わせて、より詳細なグループを作成することも可能です。リスト形式で列名を指定します。
# '支店'と'商品'の組み合わせごとに'売上'の合計を算出
sales_by_branch_item = df.groupby(['支店', '商品'])['売上'].sum()
print("\n支店と商品の組み合わせごとの売上合計:\n", sales_by_branch_item)
解説:
結果はMultiIndexのSeriesとして返され、最初のインデックスが’支店’、2番目のインデックスが’商品’を示します。
複数の集計関数を一度に適用する: agg()
異なる統計量を一度に算出したい場合、agg()(またはaggregate())メソッドが非常に便利です。
1つの列に複数の集計関数を適用する
# '支店'ごとに'売上'の合計と平均を一度に算出
agg_sales_by_branch = df.groupby('支店')['売上'].agg(['sum', 'mean'])
print("\n支店ごとの売上合計と平均:\n", agg_sales_by_branch)
解説:
agg()に集計関数の名前を文字列のリストとして渡すと、指定されたすべての統計量が計算されます。
複数の列に異なる集計関数を適用する
辞書形式で、列ごとに適用する集計関数を指定することも可能です。
# '支店'ごとに'売上'の合計と'在庫'の平均を算出
multi_col_agg = df.groupby('支店').agg({'売上': 'sum', '在庫': 'mean'})
print("\n支店ごとの売上合計と在庫平均:\n", multi_col_agg)
まとめ
Pandasのgroupby()メソッドは、データ集計と分析の強力な基盤となる機能です。単一または複数の列でデータをグループ化し、sum()、mean()、max()、min()、count()、nunique()などの様々な統計量を算出できます。さらに、agg()を組み合わせることで、複数の集計関数を一度に適用したり、列ごとに異なる集計を行ったりすることも可能です。これらのgroupby()のテクニックを使いこなして、あなたのデータからより深い洞察を引き出し、効率的な分析ワークフローを構築しましょう。
