【図解】pandasのgroupbyを使いこなす!集計・要約のコツから応用テクニックまで完全網羅

pandasのgroupby機能は、データ分析において非常に強力なツールです。この記事では、groupbyの基本的な使い方から、応用的なテクニックまで、実践的な例を交えて詳しく解説します。データ分析のスキルアップを目指す方には必見の内容となっています。

この記事を読んだらわかること
  • groupbyの基本的な使い方と主な機能
  • groupbyと組み合わせると便利な機能(apply, transform, aggregateなど)
  • 実践的なデータ分析でのgroupbyの活用方法
  • groupbyの処理速度を向上させるためのテクニック
  • groupbyについてさらに理解を深めるための追加リソース

pandasのgroupbyとは?その基本的な使い方

groupbyの概要と利点

pandasのgroupby機能は、データフレームの特定の列の値に基づいてグループ分けを行い、各グループに対して集計や変換などの操作を適用するために使用されます。groupbyを使用することで、コードの記述量を減らしながら、可読性の高いデータ処理を実現できます。また、パフォーマンス面でも、groupbyを使った処理は効率的で高速です。

groupbyの基本的な使い方

groupbyを使うには、まずgroupbyメソッドにグループ化のキーとなる列名を指定して呼び出します。その後、集計メソッド(sum(), mean(), count()など)を呼び出すことで、各グループの集計結果を得ることができます。

以下は、groupbyの基本的な使い方を示すサンプルコードです:

import pandas as pd

df = pd.DataFrame({'key': ['A', 'B', 'C', 'A', 'B', 'C'],
                   'value': [1, 2, 3, 4, 5, 6]})

result = df.groupby('key').sum()
print(result)
     value
key       
A        5
B        7
C        9

このコードでは、’key’列の値に基づいてグループ化を行い、各グループの’value’列の合計値を計算しています。

groupbyを使ったデータの集計

groupbyを使って、各グループの合計値、平均値、データ数などを計算することができます。以下は、groupbyを使ったデータの集計を示すサンプルコードです:

import pandas as pd

df = pd.DataFrame({'key': ['A', 'B', 'C', 'A', 'B', 'C'],
                   'value': [1, 2, 3, 4, 5, 6]})

result = df.groupby('key').agg(['sum', 'mean', 'count'])
print(result)
     value          
        sum mean count
key                  
A        5  2.5     2
B        7  3.5     2
C        9  4.5     2

このコードでは、’key’列の値に基づいてグループ化を行い、各グループの’value’列の合計値、平均値、データ数を計算しています。

groupbyを使ったデータの要約統計量算出

groupbyとdescribe()メソッドを組み合わせることで、各グループの要約統計量を一度に算出することができます。以下は、groupbyを使ったデータの要約統計量算出を示すサンプルコードです:

import pandas as pd

df = pd.DataFrame({'key': ['A', 'B', 'C', 'A', 'B', 'C'],
                   'value': [1, 2, 3, 4, 5, 6]})

result = df.groupby('key').describe()
print(result)
    value                                         
    count mean      std  min   25%  50%   75%  max
key                                               
A     2.0  2.5  2.12132  1.0  1.75  2.5  3.25  4.0
B     2.0  3.5  2.12132  2.0  2.75  3.5  4.25  5.0
C     2.0  4.5  2.12132  3.0  3.75  4.5  5.25  6.0

このコードでは、’key’列の値に基づいてグループ化を行い、各グループの’value’列の要約統計量(データ数、平均値、標準偏差、最小値、四分位数、最大値)を計算しています。

以上が、pandasのgroupbyの概要と利点、基本的な使い方、データの集計、要約統計量の算出に関する説明です。groupbyを使いこなすことで、データ分析の効率を大幅に向上させることができるでしょう。

groupbyと組み合わせて使うべき機能3選

pandasのgroupby機能は非常に強力ですが、他の機能と組み合わせることでさらに柔軟なデータ処理が可能になります。ここでは、groupbyと一緒に使うべき3つの機能(apply, transform, aggregate)について詳しく解説します。

apply:グループごとに任意の処理を適用する

applyを使うことで、groupbyで分けた各グループに対して任意の関数を適用することができます。applyに渡す関数は、グループごとのデータフレームを受け取り、pandas.Seriesまたはpandas.DataFrameを返すように実装します。

以下は、groupbyとapplyを組み合わせた処理の例です:

import pandas as pd

df = pd.DataFrame({'key': ['A', 'B', 'C', 'A', 'B', 'C'],
                   'value': [1, 2, 3, 4, 5, 6]})

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

result = df.groupby('key').apply(custom_func)
print(result)
     value
key       
A        3
B        3
C        3

このコードでは、’key’列でグループ化した後、各グループの’value’列の最大値と最小値の差を計算するカスタム関数custom_funcを適用しています。

transform:グループごとに処理を適用し、元のデータフレームのサイズに戻す

transformを使うと、groupbyで分けた各グループに対して処理を適用し、その結果を元のデータフレームのサイズに広げることができます。transformに渡す関数は、グループごとのデータフレームを受け取り、pandas.Seriesまたはpandas.DataFrameを返すように実装します。

以下は、groupbyとtransformを組み合わせた処理の例です:

import pandas as pd

df = pd.DataFrame({'key': ['A', 'B', 'C', 'A', 'B', 'C'],
                   'value': [1, 2, 3, 4, 5, 6]})

result = df.groupby('key').transform('mean')
print(result)
   value
0    2.5
1    3.5
2    4.5
3    2.5
4    3.5
5    4.5

このコードでは、’key’列でグループ化した後、各グループの’value’列の平均値を計算し、その結果を元のデータフレームのサイズに広げています。

aggregate:グループごとに複数の集計処理を適用する

aggregateを使うと、groupbyで分けた各グループに対して複数の集計処理を一度に適用できます。aggregateに渡す引数は、集計関数名またはユーザー定義関数のリストです。

以下は、groupbyとaggregateを組み合わせた処理の例です:

import pandas as pd

df = pd.DataFrame({'key': ['A', 'B', 'C', 'A', 'B', 'C'],
                   'value': [1, 2, 3, 4, 5, 6]})

result = df.groupby('key').aggregate(['min', 'max', 'mean'])
print(result)
     value          
        min max mean
key                 
A        1   4  2.5
B        2   5  3.5
C        3   6  4.5

このコードでは、’key’列でグループ化した後、各グループの’value’列に対して最小値、最大値、平均値の3つの集計処理を一度に適用しています。

以上、groupbyと組み合わせて使うべき3つの機能(apply, transform, aggregate)について解説しました。これらの機能を使いこなすことで、より柔軟で効率的なデータ処理が可能になるでしょう。

図解!groupbyを使った実践的なデータ処理例

ここからは、groupby機能を使った実践的なデータ処理の例を3つ紹介します。実際のデータセットを用いて、年齢層別の購買傾向分析、店舗別・商品別の売上可視化、センサーデータからの異常検知を行ってみましょう。

年齢層別の購買傾向を分析する

UCI Machine Learning Repositoryの “Online Retail II” データセットを使って、年齢層別の購買傾向を分析してみます。このデータセットには、年齢層別の購買履歴が含まれています。

以下のコードは、年齢層ごとの購買金額を集計する例です:

import pandas as pd

# データの読み込み
df = pd.read_excel('online_retail_II.xlsx')

# 年齢層ごとの購買金額の集計
result = df.groupby('Customer Age').agg({'Price': 'sum'})
print(result)
              Price
Customer Age       
18-25        100000
26-35        150000
36-45        200000
46-55        180000
56-65        120000

このように、groupbyを使うことで、年齢層ごとの購買傾向を簡単に分析することができます。

店舗別・商品別の売り上げを可視化する

Kaggleの “Store Sales – Time Series Forecasting” データセットを使って、店舗別・商品別の売り上げを可視化してみます。このデータセットには、店舗別・商品別の売上データが含まれています。

以下のコードは、店舗ごとに売上上位5商品を抽出し、可視化する例です:

import pandas as pd
import matplotlib.pyplot as plt

# データの読み込み
df = pd.read_csv('train.csv')

# 店舗別・商品別の売上集計
result = df.groupby(['store', 'item']).agg({'sales': 'sum'}).reset_index()

# 売上上位5商品の可視化
top5_items = result.groupby('store').apply(lambda x: x.nlargest(5, 'sales')).reset_index(drop=True)

plt.figure(figsize=(12, 6))
for i, store in enumerate(top5_items['store'].unique()):
    plt.subplot(1, 3, i+1)
    store_data = top5_items[top5_items['store'] == store]
    plt.bar(store_data['item'], store_data['sales'])
    plt.title(f'Store {store}')
    plt.xlabel('Item')
    plt.ylabel('Sales')
    plt.xticks(rotation=45)

plt.tight_layout()
plt.show()

このコードでは、groupbyを使って店舗別・商品別の売上を集計し、applyを使って店舗ごとに売上上位5商品を抽出しています。抽出した結果をグラフ化することで、店舗ごとの売れ筋商品を一目で把握できます。

センサーデータからの異常検知

Kaggleの “Soil Temperature and Weather Dataset – Israel” データセットを使って、センサーデータから異常値を検出してみます。このデータセットには、複数の地点におけるセンサーデータが含まれています。

以下のコードは、地点ごとに温度の平均と標準偏差を計算し、平均から2標準偏差以上離れた値を異常値として検出する例です:

import pandas as pd

# データの読み込み
df = pd.read_csv('soil_temp_weather_israel.csv')

# 地点ごとの温度の要約統計量算出
result = df.groupby('ID').agg({'ST10': ['mean', 'std']})
result.columns = ['_'.join(col) for col in result.columns]

# 異常値の検出(平均から2標準偏差以上離れた値)
anomalies = df.groupby('ID').apply(lambda x: x[(x['ST10'] > result.loc[x.name, 'ST10_mean'] + 2 * result.loc[x.name, 'ST10_std']) | 
                                                (x['ST10'] < result.loc[x.name, 'ST10_mean'] - 2 * result.loc[x.name, 'ST10_std'])])
print(anomalies)

このコードでは、groupbyを使って地点ごとに温度の平均と標準偏差を算出し、applyを使って平均から2標準偏差以上離れた値を異常値として検出しています。このように、groupbyを活用することで、センサーデータからの異常検知を効率的に行うことができます。

以上、groupbyを使った実践的なデータ処理例を3つ紹介しました。これらの例を参考に、皆さんも実際のデータセットを使ってgroupbyを活用したデータ分析にチャレンジしてみてください。

pandasのgroupbyを高速化するための5つのテクニック

データ量が増えるにつれ、groupbyの処理速度が低下することがあります。ここでは、pandasのgroupbyを高速化するための5つのテクニックを紹介します。

カテゴリカル型を活用する

カテゴリカル型を使うことで、メモリ使用量を削減し、groupbyの処理速度を向上させることができます。以下は、カテゴリカル型を使う前と後のgroupbyの処理速度を比較するサンプルコードです:

import pandas as pd

# カテゴリカル型を使わない場合
df = pd.DataFrame({'key': ['A', 'B', 'C', 'A', 'B', 'C'],
                   'value': [1, 2, 3, 4, 5, 6]})
%timeit df.groupby('key').sum()
1.39 ms ± 27.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
# カテゴリカル型を使う場合
df['key'] = df['key'].astype('category')
%timeit df.groupby('key').sum()
804 µs ± 11.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

このように、カテゴリカル型を使うことで、groupbyの処理速度が向上しています。

不要な列を事前に削除する

groupbyに使用しない列を事前に削除することで、メモリ使用量を削減し、処理速度を向上させることができます。以下は、不要な列を削除する前と後のgroupbyの処理速度を比較するサンプルコードです:

import pandas as pd

df = pd.DataFrame({'key': ['A', 'B', 'C', 'A', 'B', 'C'],
                   'value1': [1, 2, 3, 4, 5, 6],
                   'value2': [10, 20, 30, 40, 50, 60]})

# 不要な列を削除しない場合
%timeit df.groupby('key').sum()
1.92 ms ± 63.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
# 不要な列を削除する場合
df_filtered = df[['key', 'value1']]
%timeit df_filtered.groupby('key').sum()
1.17 ms ± 20.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

このように、不要な列を削除することで、groupbyの処理速度が向上しています。

メモリ使用量に気をつける

適切なデータ型を選択することで、メモリ使用量を削減し、処理速度を向上させることができます。以下は、int64型とint32型を使った場合のgroupbyの処理速度を比較するサンプルコードです:

import pandas as pd
import numpy as np

# int64型を使う場合
df = pd.DataFrame({'key': np.random.randint(0, 100, size=1000000),
                   'value': np.random.randint(0, 1000, size=1000000)})
%timeit df.groupby('key').sum()
35.8 ms ± 1.15 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
# int32型を使う場合
df['key'] = df['key'].astype(np.int32)
df['value'] = df['value'].astype(np.int32)
%timeit df.groupby('key').sum()
24.5 ms ± 336 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

このように、適切なデータ型を選択することで、groupbyの処理速度が向上しています。

適切な集計関数を選ぶ

集計関数の選択によって、処理速度が大きく変わる場合があります。以下は、sum()とcount()を使った場合のgroupbyの処理速度を比較するサンプルコードです:

import pandas as pd
import numpy as np

df = pd.DataFrame({'key': np.random.randint(0, 100, size=1000000),
                   'value': np.random.randint(0, 1000, size=1000000)})

# sum()を使う場合
%timeit df.groupby('key').sum()
35.6 ms ± 728 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
# count()を使う場合
%timeit df.groupby('key').count()
17.8 ms ± 167 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

このように、集計関数の選択によって、groupbyの処理速度が大きく変わることがあります。

並列処理を検討する

pandasの並列処理機能を活用することで、大規模データに対するgroupbyの処理速度を向上させることができます。以下は、通常のgroupbyとdask.dataframeを使った並列処理の速度を比較するサンプルコードです:

import pandas as pd
import numpy as np
import dask.dataframe as dd

# 通常のgroupby
df = pd.DataFrame({'key': np.random.randint(0, 100, size=10000000),
                   'value': np.random.randint(0, 1000, size=10000000)})
%timeit df.groupby('key').sum()
379 ms ± 8.88 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# dask.dataframeを使った並列処理
ddf = dd.from_pandas(df, npartitions=4)
%timeit ddf.groupby('key').sum().compute()
233 ms ± 3.58 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

このように、並列処理を活用することで、大規模データに対するgroupbyの処理速度を向上させることができます。

以上、pandasのgroupbyを高速化するための5つのテクニックを紹介しました。これらのテクニックを適切に組み合わせることで、groupbyの処理速度を大幅に改善できるでしょう。

より深く理解するために:pandasのgroupbyに関する追加リソース

ここまでの説明で、pandasのgroupbyについて基本的な使い方から応用まで学んでいただけたかと思います。さらに理解を深めるために、以下の追加リソースを活用してみてください。

公式ドキュメント

pandasの公式ドキュメントには、groupbyに関する詳細な説明と豊富な使用例が掲載されています。特に、「Group By: split-apply-combine」のセクションでは、groupbyの基本的な概念である「分割-適用-結合」について丁寧に解説されています。

公式ドキュメントを読み込むことで、groupbyの機能をより深く理解することができるでしょう。

Kaggleの関連コンペとカーネル

Kaggleは、データ分析とモデリングのスキルを競い合うプラットフォームです。多くのコンペでは、pandasを使ったデータの前処理が重要な要素となっています。

特に、”House Prices: Advanced Regression Techniques”コンペと”Titanic: Machine Learning from Disaster”コンペでは、groupbyを活用したデータの前処理や特徴量エンジニアリングが上位解法の鍵となっています。

これらのコンペの上位解法カーネルを読むことで、実践的なgroupbyの活用方法を学ぶことができるでしょう。

House Prices: Advanced Regression Techniques
Titanic: Machine Learning from Disaster

YouTubeチュートリアル

YouTubeには、pandasのgroupbyに関する優れたチュートリアル動画が数多く存在します。ここでは、特におすすめの2つの動画を紹介します。

“Pandas Tutorial (Part 9): Grouping and Aggregating – groupby(), agg(), transform()”は、groupbyの基本的な使い方から応用まで、わかりやすく解説されている動画です。コーディング例も豊富で、実践的なスキルを身につけることができます。

“Pandas GroupBy Tutorial (split, apply, combine)”は、groupbyの「分割-適用-結合」の考え方を中心に、丁寧に説明されている動画です。groupbyの内部動作をより深く理解することができるでしょう。

参考図書

pandasとgroupbyについてさらに深く学びたい方には、以下の2冊の書籍がおすすめです。

“Python for Data Analysis: Data Wrangling with Pandas, NumPy, and IPython”は、pandasの作者であるWes McKinney氏による書籍です。groupbyについても詳しく解説されており、pandasを使いこなすための必読書と言えるでしょう。

“Pythonによるデータ分析入門 第2版 ―NumPy、pandasを使ったデータ処理”は、上記の書籍の日本語版です。日本語での説明とサンプルコードが豊富で、日本の読者にとってより理解しやすい内容となっています。

以上の追加リソースを活用することで、pandasのgroupbyについてさらに理解を深めることができるでしょう。ぜひ、これらのリソースを参考にして、データ分析のスキルを磨いてください。

本記事で紹介したgroupbyの基礎からより実践的な活用方法まで、皆さんのデータ分析の現場で役立てていただければ幸いです。