Pandas & NumPy Academy · レッスン

pivot_table:クロス集計

pd.pivot_tableでExcel形式のピボットテーブルを作成し、index、columns、values、aggfuncを設定します。

レッスン 1/413 ステップ

「pivot_table:クロス集計」はCoddyKit上の無料Pandas & NumPy Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPandas & NumPy Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Pandas & NumPy Academyコースには全4レッスンが含まれています。

ピボットテーブルとは

ピボットテーブルは、2つのカテゴリ次元でデータをクロス集計する表です。一方の次元が行、もう一方が列を形成し、各セルには集計値が入ります。Excelでピボットテーブルを作成したことがあれば、すぐにイメージできるでしょう。Pandasにはpd.pivot_table()(およびDataFrameのメソッド版)が用意されており、このような集計表をすべてPythonで作成できます。

基本的なpivot_tableの呼び出し

pd.pivot_table()の主なパラメータは4つあります。values(集計対象の列)、index(行になる列)、columns(列になる列)、aggfunc(集計関数。デフォルトは'mean')です。結果はDataFrameになり、各セルには対応する行と列の組み合わせについて集計された値が入ります。

import pandas as pd

df = pd.DataFrame({
    'region':  ['East', 'West', 'East', 'West', 'East', 'West'],
    'product': ['A',    'A',    'B',    'B',    'A',    'B'],
    'revenue': [200,    340,    150,    290,    310,    410]
})

table = pd.pivot_table(df,
                       values='revenue',
                       index='region',
                       columns='product',
                       aggfunc='sum')
print(table)
# product    A    B
# region
# East     510  150
# West     340  700

aggfuncの選択

aggfuncパラメータには、NumPyやPandasの集計関数の文字列名、呼び出し可能オブジェクト、または呼び出し可能オブジェクトのリストを指定できます。よく使う選択肢は、合計の'sum'、平均の'mean'、頻度の'count'、最大値・最小値の'min'/'max'です。リストを渡すと、各集計関数が列のMultiIndexのそれぞれのレベルになります。

# Using mean (default)
table_mean = pd.pivot_table(df, values='revenue',
                            index='region', columns='product',
                            aggfunc='mean')
print(table_mean.round(1))
# product      A      B
# region
# East     255.0  150.0
# West     340.0  350.0

# Using count
table_count = pd.pivot_table(df, values='revenue',
                             index='region', columns='product',
                             aggfunc='count')
print(table_count)

fill_valueで欠損セルを処理する

行ラベルと列ラベルの組み合わせにデータがない場合、そのセルにはデフォルトでNaNが入ります。fill_valueを渡すと、欠損セルを意味のあるデフォルト値に置き換えられます。たとえば、件数や売上には0を指定できます。これにより表が読みやすくなり、後続の算術演算で意図せずNaNが生成されるのを防げます。

df2 = pd.DataFrame({
    'region':  ['East', 'West', 'East'],
    'product': ['A',    'A',    'B'],
    'revenue': [200,    340,    150]
})

# West-B combination has no data -> NaN by default
table = pd.pivot_table(df2, values='revenue', index='region',
                       columns='product', aggfunc='sum', fill_value=0)
print(table)
# product    A    B
# region
# East     200  150
# West     340    0  <- filled with 0 instead of NaN

marginsで小計を追加する

margins=Trueを渡すと、ピボットテーブルに行と列の合計を追加できます。Pandasは末尾に'All'行を、右端に'All'列を追加し、すべてのカテゴリを対象にした集計値を入れます。margins_nameを使えば、合計ラベルの名前を変更できます。これはExcelのピボットテーブルにある「総計」行に相当します。

table = pd.pivot_table(df, values='revenue', index='region',
                       columns='product', aggfunc='sum',
                       fill_value=0, margins=True, margins_name='Total')
print(table)
# product    A     B  Total
# region
# East     510   150    660
# West     340   700   1040
# Total    850   850   1700

pivot_tableで複数の値を扱う

valuesパラメータには列名のリストを指定でき、複数の指標を一度に集計できます。結果の列はMultiIndexになり、外側のレベルが値の列、内側のレベルがカテゴリになります。これにより、複数のピボットテーブルを個別に作成して結合する代わりに、1回の呼び出しで包括的な集計表を作成できます。

df['units'] = [10, 15, 8, 12, 14, 18]

table = pd.pivot_table(df,
                       values=['revenue', 'units'],
                       index='region',
                       columns='product',
                       aggfunc='sum')
print(table)
# Columns: (revenue, A), (revenue, B), (units, A), (units, B)
print(table.columns.tolist())

階層型のインデックスと列

indexまたはcolumnsにリストを渡すと、ピボットテーブルの対応する軸にMultiIndexが設定されます。これにより、より細かな集計表を作成できます。たとえば、行を地域と四半期、列を商品として、売上を分解できます。通常どおり、.locとインデックスタプルを使って下位レベルにアクセスできます。

df['quarter'] = ['Q1', 'Q1', 'Q2', 'Q2', 'Q1', 'Q2']

table = pd.pivot_table(df, values='revenue',
                       index=['region', 'quarter'],
                       columns='product',
                       aggfunc='sum', fill_value=0)
print(table)
# product         A    B
# region quarter
# East   Q1     510    0
#        Q2       0  150
# West   Q1     340    0
#        Q2       0  700

結果をフラット化する

ピボットテーブルを作成すると、インデックスはグループ化に使った列になり、複数の値を使った場合の列MultiIndexは扱いにくくなることがあります。よく使われる整理方法は、reset_index()を呼び出して行インデックスをフラット化し、その後、リスト内包表記を使って各レベルをアンダースコアで連結し、列MultiIndexを1つのレベルにまとめることです。

table = pd.pivot_table(df, values=['revenue', 'units'],
                       index='region', columns='product', aggfunc='sum')

# Flatten MultiIndex columns
table.columns = ['_'.join(str(c) for c in col) for col in table.columns]
table = table.reset_index()
print(table.columns.tolist())
# ['region', 'revenue_A', 'revenue_B', 'units_A', 'units_B']

pivot_tableとgroupby().agg()の比較

pivot_tableとgroupby().agg()は、どちらも集計統計量を生成します。違いは出力の形状です。groupby().agg()は、グループの組み合わせごとに1行を持つロング形式のDataFrameを返します。一方、pivot_tableは、一方の次元が列になるワイド形式の表を返します。ダッシュボードやレポートではピボットテーブルのワイド形式のほうが読みやすいことが多く、機械学習や統計分析を続けて行う場合はロング形式が適しています。

# Long format (groupby)
long = df.groupby(['region', 'product'])['revenue'].sum().reset_index()
print(long)
# region product  revenue
# East        A      510
# East        B      150

# Wide format (pivot_table)
wide = pd.pivot_table(df, 'revenue', 'region', 'product', 'sum', fill_value=0)
print(wide)
# product    A    B
# region
# East     510  150

ピボットテーブルの並べ替えとスタイル設定

ピボットテーブルは通常のDataFrameなので、他のPandas DataFrameと同じように、並べ替え、派生列の計算、書式設定を行えます。たとえば、特定の商品列を降順に並べ替えて、その商品の実績順に地域を順位付けしたり、各セルを行合計で割って割合の列を追加したりできます。

table = pd.pivot_table(df, 'revenue', 'region', 'product', 'sum', fill_value=0)

# Sort by product A revenue descending
table_sorted = table.sort_values('A', ascending=False)
print(table_sorted)

# Add percentage of row total
table['A_pct'] = (table['A'] / table.sum(axis=1) * 100).round(1)
print(table)

実践例:売上ダッシュボードの表

ピボットテーブルは、経営レポートやダッシュボードを作成するための中心的なツールです。一般的な流れは、元の取引データを読み込み、列に月、行に商品カテゴリを配置したピボットテーブルを作成し、合計を追加してからExcelに出力するというものです。元データから経営会議で使える表を作成するまでの処理は、Pandasの呼び出しを数回行うだけで完了します。

# Simulated monthly product revenue pivot
result = pd.pivot_table(
    df,
    values='revenue',
    index='product',
    columns='region',
    aggfunc='sum',
    fill_value=0,
    margins=True,
    margins_name='Grand Total'
)
print(result)
# Export to Excel
# result.to_excel('sales_pivot.xlsx')

理解度チェック

このレッスンで学んだpd.pivot_tableについて、理解度を確認しましょう。

レッスンのまとめ

このレッスンでは、pd.pivot_table()を使うと、一方の次元を行、もう一方を列とするクロス集計表を作成できること、fill_valueで欠損セルを処理し、margins=Trueで合計を追加できること、複数の値を一度に集計できること、そしてピボットテーブルはレポートに適したワイド形式で出力されることを学びました。次は、逆方向の操作であるmelt()を使って、ワイドデータをロング形式に戻す方法を学びます。

無料で開始

AI チューターと学ぶ Python — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
30
レッスン
120

よくある質問

「pivot_table:クロス集計」レッスンは無料ですか?

はい。「pivot_table:クロス集計」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Pandas & NumPy Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Pandas & NumPy Academyコースには全4レッスンが含まれています。

「pivot_table:クロス集計」で何を学びますか?

pd.pivot_tableでExcel形式のピボットテーブルを作成し、index、columns、values、aggfuncを設定します。 ブラウザで直接実行するハンズオンコードでPandas & NumPy Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Pandas & NumPy Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのPandas & NumPy Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「pivot_table:クロス集計」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このPandas & NumPy Academyレッスンでコードを書いて実行できますか?

はい。すべてのPandas & NumPy Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. pivot_table:クロス集計
  2. melt:横持ち形式から縦持ち形式へ
  3. MultiIndexでのstackとunstack
  4. 度数表に使うcrosstab
← Pandas & NumPy Academyに戻る