Pandas のグループ化と集計

PandasBeginner
オンラインで実践に進む

はじめに

データのグループ化と集計は、データ分析における基本的な操作です。これにより、特定の基準に基づいて大規模なデータセットを小さなグループに分割し、各グループの要約統計量を計算することができます。このプロセスは、パターンを明らかにし、セグメントを比較し、生データから意味のある洞察を導き出すために不可欠です。

Python のデータ分析ライブラリである Pandas では、この「分割 - 適用 - 結合(split-apply-combine)」戦略は、主に強力なgroupby()メソッドによって処理されます。この実験(Lab)では、groupby()を使用してグループ化と集計を実行する方法を学びます。単一の列でデータをグループ化し、集計関数を適用し、複数の関数を一度に使用し、複数の列でグループ化し、最後に、出力を標準的な DataFrame にフォーマットすることから始めます。

単一列での groupby によるグループ化

このステップでは、DataFrame をグループに分割するための groupby() メソッドの基本的な使い方を学びます。groupby() メソッド自体は何も計算しませんが、DataFrameGroupBy オブジェクトを返します。このオブジェクトには、各グループに計算を適用するために必要なすべての情報が含まれています。

まず、サンプル DataFrame を Category 列でグループ化します。これにより、「Electronics」、「Clothing」、「Books」のそれぞれに異なるグループが作成されます。

左側のエディタで main.py ファイルを開いてください。DataFrame を作成するための初期コードはすでに記述されています。以下のコードを main.py ファイルの末尾に追加してください。

## 'Category' 列でグループ化
grouped_by_category = df.groupby('Category')

## 結果は DataFrameGroupBy オブジェクトです
print("Type of the grouped object:")
print(type(grouped_by_category))

## 内容を確認するには、グループを反復処理できます
print("\nIterating over groups to see their content:")
for name, group in grouped_by_category:
    print(f"\nGroup: {name}")
    print(group)

次に、ターミナルからスクリプトを実行して出力を確認します。

python3 main.py

元の DataFrame の後に、groupby オブジェクトの型、そして各グループの内容が表示されます。これは、DataFrame が 'Category' 列のユニークな値に基づいて正常に分割されたことを示しています。

Original DataFrame:
      Category Region  Sales  Units
0  Electronics  North   1200     10
1     Clothing  South    800     25
2  Electronics  North   1500      8
3        Books   West    300     15
4     Clothing   East    900     20
5        Books   West    450     18

==============================

Type of the grouped object:
<class 'pandas.core.groupby.generic.DataFrameGroupBy'>

Iterating over groups to see their content:

Group: Books
  Category Region  Sales  Units
3    Books   West    300     15
5    Books   West    450     18

Group: Clothing
   Category Region  Sales  Units
1  Clothing  South    800     25
4  Clothing   East    900     20

Group: Electronics
      Category Region  Sales  Units
0  Electronics  North   1200     10
2  Electronics  North   1500      8

グループに対する sum 集計の適用

このステップでは、作成したグループに集計関数を適用する方法を学びます。データをグループ化した後、最も一般的な次のステップは、各グループに対して sum()mean()count()max() などの計算を実行することです。

製品カテゴリごとの総売上を計算してみましょう。これを行うには、まず Category でグループ化し、次に Sales 列を選択して sum() 関数を適用します。

以下のコードを main.py ファイルの末尾に追加してください。前のステップの for ループを削除すると、出力をきれいに保つことができます。

## 'Category' でグループ化し、各グループの 'Sales' の合計を計算
category_sales_sum = df.groupby('Category')['Sales'].sum()

print("Total sales per category:")
print(category_sales_sum)

ファイルを保存して、再度実行します。

python3 main.py

出力には、インデックスがカテゴリ名で、値がそのカテゴリの総売上である Pandas Series が表示されます。

... (previous output) ...

Total sales per category:
Category
Books           750
Clothing       1700
Electronics    2700
Name: Sales, dtype: int64

これは、データを要約するための強力かつ簡潔な方法です。同じロジックを他の数値列に適用したり、mean() のような他の集計関数を使用して平均を求めたりすることもできます。

agg による複数関数の集計

このステップでは、agg() メソッドを使用して、グループに複数の集計関数を同時に適用する方法を学びます。これは、合計売上と平均売上の両方など、複数の要約統計量を一度に計算したい場合に非常に役立ちます。

agg() メソッドには、文字列のリストを渡すことができます。各文字列は集計関数の名前です。ここでは、各 Category に対して Salessummean の両方を計算してみましょう。

以下のコードを main.py ファイルの末尾に追加してください。

## 'Category' でグループ化し、'Sales' に複数の集計を適用
category_agg = df.groupby('Category')['Sales'].agg(['sum', 'mean'])

print("\nSum and mean of sales per category:")
print(category_agg)

ファイルを保存して実行します。

python3 main.py

出力は DataFrame になります。インデックスは引き続き Category ですが、列は階層的になり、Sales データに対する summean の両方が表示されます。

... (previous output) ...

Sum and mean of sales per category:
              sum    mean
Category
Books         750   375.0
Clothing     1700   850.0
Electronics  2700  1350.0

agg() メソッドは、グループ化されたデータの包括的な要約を生成するための柔軟な方法を提供します。

複数列でのグループ化

このステップでは、DataFrame を複数の列でグループ化する方法を学びます。これは、より詳細なグループを作成し、異なるカテゴリ間の相互作用を分析するのに役立ちます。これを行うには、groupby() メソッドに列名のリストを渡すだけです。

RegionCategory の各組み合わせに対する総売上を見つけましょう。これにより、異なる製品カテゴリの売上が地域間でどのように分布しているかがわかります。

以下のコードを main.py ファイルの末尾に追加してください。

## 複数列でグループ化:'Region' と 'Category'
multi_group_sum = df.groupby(['Region', 'Category'])['Sales'].sum()

print("\nTotal sales per Region and Category:")
print(multi_group_sum)

ファイルを保存してスクリプトを実行します。

python3 main.py

出力には、行に MultiIndex が表示され、最初のレベルが Region、2 番目のレベルが Category になります。これにより、売上の詳細な内訳が提供されます。

... (previous output) ...

Total sales per Region and Category:
Region  Category
East    Clothing        900
North   Electronics    2700
South   Clothing        800
West    Books           750
Name: Sales, dtype: int64

ご覧のとおり、複数の列でグループ化することにより、データセットのより深く階層的な分析が可能になります。

グループ化された DataFrame のインデックスリセット

このステップでは、グループ化された出力を通常の DataFrame に戻す方法を学びます。ここでは、グループ化キーがインデックスではなく列になります。デフォルトでは、groupby() はグループ化キーを結果の Series または DataFrame のインデックスにします。場合によっては、さらなる処理や視覚化のために「フラットな」DataFrame が必要になります。

これを実現する最も簡単な方法は、groupby() メソッド内で as_index=False パラメータを使用することです。

ステップ 2 の単一列でのグループ化を繰り返しますが、今回は Category を通常の列として保持します。

以下のコードを main.py ファイルの末尾に追加してください。

## 'Category' でグループ化し集計するが、'Category' は列として保持する
category_sales_flat = df.groupby('Category', as_index=False)['Sales'].sum()

print("\nGrouped data with 'Category' as a column:")
print(category_sales_flat)

ファイルを保存して、もう一度実行します。

python3 main.py

出力を観察してください。Category がインデックスになる代わりに、現在は新しい DataFrame の最初の列になっており、DataFrame は標準の整数インデックス(0、1、2)を持っています。

... (previous output) ...

Grouped data with 'Category' as a column:
      Category  Sales
0        Books    750
1     Clothing   1700
2  Electronics   2700

この形式は、後続のデータ操作タスクにとってより便利な場合が多いです。別の方法として、グループ化された結果に対して .reset_index() を呼び出すこともでき、これは同じ結果をもたらします。

まとめ

Pandas のグループ化と集計に関するこの実験を完了したことをお祝いします!データ分析において、Pandas ライブラリの最も強力で一般的に使用される機能の 1 つを学びました。

この実験では、以下のことを練習しました。

  • df.groupby('column_name') を使用して DataFrame をグループに分割する。
  • グループに .sum() のような単一の集計関数を適用する。
  • .agg() メソッドを使用して複数の集計関数を一度に適用する。
  • df.groupby(['col1', 'col2']) を使用して複数の列でグループ化し、階層的な概要を作成する。
  • as_index=False パラメータを使用して、groupby 操作からフラットな DataFrame を作成する。

これらのテクニックを習得することは、Python と Pandas を使用したデータ操作と分析に習熟するための重要なステップです。