Pandas pivot
と pivot_table
を徹底解説!データ分析での使い分けと応用
本記事で pandas pivot の基本と注意点を最初に整理します。データ分析をするとき、データを表に整理することが大切です。特に、元のデータを見たい形に並べ替える「ピボット」という操作はよく使われます。これは、バラバラに記録されたデータ(ロング形式)を、分析しやすい形(ワイド形式)に変換するデータ集計やデータ分析の重要なステップです。
たとえば、日付ごとにバラバラに記録された売上データを、「月」を横軸(列)に、「商品」を縦軸(行)にして、それぞれの「売上合計」がすぐわかるような表にする、といった場合に使います。このように、元のバラバラした形(ロング形式と呼びます)から、分析しやすい形(ワイド形式と呼びます)に変換するのがピボットです。
Pandas という便利なツールには、このピボットを行うための pivot()
と pivot_table()
という機能があります。どちらも似ていますが、使うデータに同じ組み合わせ(例:同じ月、同じ商品)が複数あるかどうかや、合計などの計算をするかどうかで使い分ける必要があります。特に、重複するデータを集計しながらクロス集計表を作成する際には pivot_table()
が強力です。
この記事では、Pandas の pivot
と pivot_table
の基本的な使い方から、同じ組み合わせのデータをまとめる方法、複数の項目で整理する方法、そしてどちらの機能を選べば良いかまで、実際のコードを見ながら詳しく説明します。「pandas pivot」 や 「pandas pivot_table」 の使い方を知りたい方、データを分かりやすく整理したい方、データ分析やデータ集計を効率化したい方はぜひ読んでみてください。
▶️ Pandas pivotやpivot_tableの公式ドキュメントも参考にしてください:
Pandas pivot() の基本と使い方:重複しないデータの変換
Pandas の pivot()
関数は、データフレームをシンプルに再形成するために使用されます。この関数は、index
, columns
, values
の 3 つの引数を取り、指定した列をインデックス、カラム、値として新しいデータフレームを作成します。データ分析の初期段階で、重複のないシンプルなデータを整形するのに役立ちます。
重要な点として、pivot()
は index
と columns
で指定したキーの組み合わせが一意である(重複がない)データに対してのみ使用できます。
まずは、pivot()
を使うための重複のないサンプル売上データを作成しましょう。このデータは、各月・各商品の売上が1行に記録されており、重複する組み合わせはありません。
import pandas as pd
# 重複のないデータを作成
unique_sales_data = {'月': ['2023-01', '2023-01', '2023-02', '2023-02', '2023-03', '2023-03'],
'商品': ['りんご', 'バナナ', 'りんご', 'バナナ', 'りんご', 'バナナ'],
'売上(円)': [1000, 800, 1100, 850, 1300, 950]}
unique_sales_df = pd.DataFrame(unique_sales_data)
display(unique_sales_df)
月 | 商品 | 売上(円) | |
---|---|---|---|
0 | 2023-01 | りんご | 1000 |
1 | 2023-01 | バナナ | 800 |
2 | 2023-02 | りんご | 1100 |
3 | 2023-02 | バナナ | 850 |
4 | 2023-03 | りんご | 1300 |
5 | 2023-03 | バナナ | 950 |
この重複のない unique_sales_df
を使って、pivot()
の基本的な使い方を見てみましょう。ここでは、「月」を新しいデータフレームのインデックス、「商品」をカラム、「売上(円)」を値としてピボットします。
unique_sales_pivot = unique_sales_df.pivot(index='月', columns='商品', values='売上(円)')
display(unique_sales_pivot)
商品 | りんご | バナナ |
---|---|---|
月 | ||
2023-01 | 1000 | 800 |
2023-02 | 1100 | 850 |
2023-03 | 1300 | 950 |
Pandas pivot_table():重複データの集計と柔軟なピボット
pandas.pivot_table()
は、pivot()
よりも高機能で、特にインデックスとカラムの組み合わせに重複があるデータの集計に特化しています。データ集計(Aggregation)を行いながらデータをピボットできる点が pivot()
との最大の違いです。これにより、複雑なクロス集計表を簡単に作成できます。
pivot_table() は pivot() の引数 (index
, columns
, values
) に加えて、aggfunc
という重要な引数を持っています。aggfunc
には、重複する値に対して適用したい集計関数(例: ‘sum’, ‘mean’, ‘count’, np.sum
など)を指定します。
先ほどの unique_sales_df
は重複がありませんでしたが、実際のビジネスデータでは同じ月、同じ商品でも複数の店舗や取引でデータが重複することがよくあります。このような場合に pivot_table()
が役立ちます。データ分析において、このような重複データの集計は不可欠です。
重複を含むサンプルデータ sales_df
を使用して、pivot_table()
の使い方を見ていきましょう。このデータでは、同じ「月」と「商品」の組み合わせで複数の「店舗」のデータが含まれており、データ集計が必要なケースです。
sales_data = {'月': ['2023-01', '2023-01', '2023-01', '2023-02', '2023-02', '2023-02', '2023-03', '2023-03', '2023-03'],
'店舗': ['A', 'A', 'B', 'B', 'A', 'A', 'B', 'B', 'A'],
'商品': ['りんご', 'バナナ', 'りんご', 'バナナ', 'りんご', 'バナナ', 'りんご', 'バナナ', 'バナナ'],
'売上(円)': [1000, 800, 1200, 900, 1100, 850, 1300, 950, 850],
'売上原価(円)': [700, 500, 700, 600, 700, 400, 700, 550, 500]}
sales_df = pd.DataFrame(sales_data)
display(sales_df)
月 | 店舗 | 商品 | 売上(円) | 売上原価(円) | |
---|---|---|---|---|---|
0 | 2023-01 | A | りんご | 1000 | 700 |
1 | 2023-01 | A | バナナ | 800 | 500 |
2 | 2023-01 | B | りんご | 1200 | 700 |
3 | 2023-02 | B | バナナ | 900 | 600 |
4 | 2023-02 | A | りんご | 1100 | 700 |
5 | 2023-02 | A | バナナ | 850 | 400 |
6 | 2023-03 | B | りんご | 1300 | 700 |
7 | 2023-03 | B | バナナ | 950 | 550 |
8 | 2023-03 | A | バナナ | 850 | 500 |
Pandas pivot() の重要な制約:重複データによるエラー
pandas.pivot()
は、index
と columns
で指定したキーの組み合わせが一意である場合にのみ機能します。もし、指定した index
と columns
の組み合わせに複数の行が該当する場合、pivot()
はどの値を新しいデータフレームに配置すれば良いか判断できず、ValueError: Index contains duplicate entries, cannot reshape
のようなエラーが発生します。
例えば、以下のデータのように、2023-01月のりんごの売上データが複数存在する場合、unique_sales_df.pivot(index='月', columns='商品', values='売上(円)')
を実行するとエラーになります。
月 | 商品 | 売上(円) |
---|---|---|
2023-01 | りんご | 1000 |
2023-01 | りんご | 1500 |
↑この重複がエラーの原因
このように、集計せずに単純なデータ再形成を行いたい場合に pivot()
は便利ですが、データの重複が少しでもある場合は、後述する pivot_table()
を使う必要があります。
sales_df
を使って、「月」をインデックス、「商品」をカラム、「売上(円)」を値として pivot_table()
を実行し、重複する「月」と「商品」の組み合わせの「売上(円)」を合計してみましょう。aggfunc='sum'
を指定します。
sales_pivot_table_sum = sales_df.pivot_table(index='月', columns='商品', values='売上(円)', aggfunc='sum')
display(sales_pivot_table_sum)
商品 | りんご | バナナ |
---|---|---|
月 | ||
2023-01 | 2200 | 800 |
2023-02 | 1100 | 1750 |
2023-03 | 1300 | 1800 |
ご覧のように、pivot_table()
は重複する「月」と「商品」の組み合わせ(例: 2023-03 月のバナナ)に対して、指定した集計関数 (sum
) を適用して結果を返します。2023-03 月のバナナの売上は、店舗 B (950 円) と店舗 A (850 円) の合計値 (950 + 850 = 1800 円) となっています。このように、pivot_table()
を使うことで、重複するデータを適切に集計し、クロス集計表を作成できます。
同様に、平均を計算したい場合は aggfunc='mean'
を指定します。ここでは「売上原価(円)」の平均を見てみましょう。これもデータ集計の一種です。
sales_pivot_table_mean = sales_df.pivot_table(index='月', columns='商品', values='売上原価(円)', aggfunc='mean')
display(sales_pivot_table_mean)
商品 | りんご | バナナ |
---|---|---|
月 | ||
2023-01 | 700.0 | 500.0 |
2023-02 | 700.0 | 500.0 |
2023-03 | 700.0 | 525.0 |
Pandas pivot と pivot_table の使い分け まとめ
Pandas でデータフレームのピボットを行う際に、pivot()
と pivot_table()
のどちらを使うべきか迷うことがあります。以下にそれぞれの特徴と使い分けのポイントをまとめます。データ分析の目的に応じて適切な関数を選ぶことが重要です。
pandas.pivot()
:index
とcolumns
で指定するキーの組み合わせが一意であるデータにのみ使用できます。単純なデータの形を変える(再形成する)ことに特化しており、集計は行いません。重複がないことが確実な、シンプルなデータ変換に適しています。データ分析の初期段階での整形に利用されることがあります。pandas.pivot_table()
:index
とcolumns
で指定するキーの組み合わせに重複があっても使用できます。重複する値に対してaggfunc
で指定した集計処理を行います。データ集計と同時にデータの形を変換したい場合や、データの重複が予想される場合に適しています。これにより、詳細なクロス集計表を作成できます。
結論として、データの重複の可能性がある場合は、迷わず pivot_table()
を使用するのが安全で一般的です。 データ分析において、生のデータには重複が含まれることが多いため、pivot_table()
がより頻繁に利用されます。重複がないことが保証されている、非常にシンプルなケースでのみ pivot()
を検討すると良いでしょう。
Pandas pivot_table() の応用テクニック:複数条件での集計と詳細設定
pivot_table()
は、単一の列だけでなく、複数の列を組み合わせてインデックスやカラムとして使用することで、より複雑で多角的なデータ集計・データ分析を行うことができます。これにより、データの階層的な構造を表現したクロス集計表を作成することが可能です。データ分析において、多次元的な視点からデータを把握するのに非常に役立ちます。
複数レベルのインデックス (MultiIndex) の作成
index
引数に列名のリストを指定することで、複数のレベルを持つ階層的なインデックス(MultiIndex)を作成できます。例えば、「月」と「店舗」をインデックス、「商品」をカラム、「売上原価(円)」を値として、それぞれの合計を集計してみましょう。これはデータ集計の一例であり、店舗ごとの月別売上原価の傾向を把握するのに役立ちます。
sales_pivot_multi_index = sales_df.pivot_table(index=['月', '店舗'], columns='商品', values='売上原価(円)', aggfunc='sum')
display(sales_pivot_multi_index)
商品 | りんご | バナナ | |
---|---|---|---|
月 | 店舗 | ||
2023-01 | A | 700.0 | 500.0 |
B | 700.0 | NaN | |
2023-02 | A | 700.0 | 400.0 |
B | NaN | 600.0 | |
2023-03 | A | NaN | 500.0 |
B | 700.0 | 550.0 |
このように、外側のレベルに「月」、その内側のレベルに「店舗」という階層構造を持つインデックスが作成されました。
複数レベルのカラム (MultiColumn) の作成
同様に、columns
引数に列名のリストを指定することで、複数のレベルを持つ階層的なカラム(MultiColumn)を作成できます。ここでは、「月」をインデックス、「店舗」と「商品」をカラム、「売上(円)」を値として、それぞれの合計を集計してみましょう。
sales_pivot_multi_columns = sales_df.pivot_table(index='月', columns=['店舗', '商品'], values='売上(円)', aggfunc='sum')
display(sales_pivot_multi_columns)
店舗 | A | B | ||
---|---|---|---|---|
商品 | りんご | バナナ | りんご | バナナ |
月 | ||||
2023-01 | 1000.0 | 800.0 | 1200.0 | NaN |
2023-02 | 1100.0 | 850.0 | NaN | 900.0 |
2023-03 | NaN | 850.0 | 1300.0 | 950.0 |
外側のレベルに「店舗」、その内側のレベルに「商品」という階層構造を持つカラムが作成されました。pivot_table()
を活用することで、このように様々な切り口でデータを集計し、ビジネスの意思決定に役立つインサイトを得ることが可能になります。
>『インサイト』とは、データ分析から得られる、物事の本質を見抜く洞察や、次に取るべき行動のヒントになるような深い理解のことです。
実社会での具体的な応用例
pivot_table()
は様々な種類のデータ分析に活用できます。いくつか具体的なシナリオを見てみましょう。これにより、いかにpivot_table()
がデータ集計とクロス集計表作成に役立つかが分かります。
例 1:EC サイトの売上データ
EC サイトの売上データがあるとします。ここには、注文 ID、顧客 ID、購入日、商品カテゴリ、商品名、価格などの情報が含まれています。pivot_table()
を使うと、以下のようなデータ分析が可能です。
- 月別の商品カテゴリ別売上集計:
sales_df.pivot_table(index='購入月', columns='商品カテゴリ', values='価格', aggfunc='sum')
→ 各月のどの商品カテゴリがどれだけ売れているか一目で把握できます。これは典型的なクロス集計表を用いたデータ集計です。
- 顧客別の購入商品集計:
sales_df.pivot_table(index='顧客ID', columns='商品名', values='注文ID', aggfunc='count', fill_value=0)
→ 各顧客がどの商品をいくつ購入したかを知ることができます。リピート購入されている商品を特定するのに役立ちます。顧客行動のデータ分析に繋がります。
例 2:顧客データ
顧客データには、顧客 ID、年齢、性別、居住地域、最終購入日などの情報が含まれているとします。
- 地域別の性別構成比:
customer_df.pivot_table(index='居住地域', columns='性別', values='顧客ID', aggfunc='count', fill_value=0)
→ どの地域の顧客層がどの性別に偏っているかを確認できます。これもクロス集計表によるデータ分析の一例です。
例 3:アンケートデータ
製品やサービスに関するアンケートデータがあるとします。回答者の属性(年齢層、職業など)と、各質問への回答(5 段階評価など)が含まれています。
- 年齢層別の質問評価平均:
survey_df.pivot_table(index='年齢層', columns='質問項目', values='評価点', aggfunc='mean')
→ どの年齢層が特定の質問項目に対してどのような評価をしているかの平均を知ることができます。製品改善の優先順位付けに役立ちます。アンケート結果のデータ集計とデータ分析に有効です。
これらの例のように、pivot_table()
はビジネスデータの様々な切り口でのデータ集計・データ分析に非常に強力なツールとなります。あなたの持っているデータをどのように集計・分析したいかを考え、適切な index
, columns
, values
, aggfunc
を指定することで、データから有用なインサイトを引き出すことができます。クロス集計表の作成は、データ分析の基本であり、pivot_table()
はその中心的な役割を担います。
<code>Pandas pivot_table()</code> の便利な引数とトラブルシューティング
pivot_table()
をより効果的に使用するための便利な引数や、よく遭遇する問題とその解決策について解説します。これにより、データ集計やデータ分析の効率をさらに向上させることができます。
NaN 値の扱い方 (fill_value 引数)
ピボットした結果のデータフレームで、元のデータに存在しないインデックスとカラムの組み合わせには、デフォルトで NaN
(Not a Number) が表示されます。これは、その組み合わせに対応するデータがなかったことを意味します。
分析や後続処理の都合上、これらの NaN
を特定の値(例えば 0)で埋めたい場合は、fill_value
引数を使用します。
sales_pivot_multi_columns = sales_df.pivot_table(index='月', columns=['店舗', '商品'], values='売上(円)', aggfunc='sum',fill_value=0)
display(sales_pivot_multi_columns)
店舗 | A | B | ||
---|---|---|---|---|
商品 | りんご | バナナ | りんご | バナナ |
月 | ||||
2023-01 | 1000 | 800 | 1200 | 0 |
2023-02 | 1100 | 850 | 0 | 900 |
2023-03 | 0 | 850 | 1300 | 950 |
fill_value=0 を指定することで、データが存在しなかった箇所が 0 で埋められていることが確認できます。これは、クロス集計表を見やすくしたり、後続の計算処理でエラーが出ないようにするための便利な機能です。データ分析においては、欠損値の適切な処理が重要になります。
様々な aggfunc の指定方法
aggfunc
には、集計関数名を文字列で指定する以外にも、より柔軟な指定方法があります。これにより、データ集計のニーズに合わせて多様な計算を適用できます。
- 集計関数のリスト: 複数の集計(例: 合計と平均)を一度に行いたい場合に便利です。
sales_pivot_multi_agg = sales_df.pivot_table(index='月', columns='商品', values='売上(円)', aggfunc=['sum', 'mean'])
display(sales_pivot_multi_agg)
sum | mean | |||
---|---|---|---|---|
商品 | りんご | バナナ | りんご | バナナ |
月 | ||||
2023-01 | 2200 | 800 | 1100.0 | 800.0 |
2023-02 | 1100 | 1750 | 1100.0 | 875.0 |
2023-03 | 1300 | 1800 | 1300.0 | 900.0 |
- 列ごとの集計関数を定義する辞書: 異なる列に対して異なる集計関数を適用したい場合に便利です。
values
引数も辞書形式で指定する必要があります。これは、例えば売上は合計、利益率は平均、といった異なる種類のデータ集計を同時に行いたい場合に有効です。
sales_pivot_dict_agg = sales_df.pivot_table(index='月', columns='商品', values={'売上(円)': 'sum', '売上原価(円)': 'mean'})
display(sales_pivot_dict_agg)
売上原価(円) | 売上(円) | |||
---|---|---|---|---|
商品 | りんご | バナナ | りんご | バナナ |
月 | ||||
2023-01 | 700.0 | 500.0 | 1100.0 | 800.0 |
2023-02 | 700.0 | 500.0 | 1100.0 | 875.0 |
2023-03 | 700.0 | 525.0 | 1300.0 | 900.0 |
大規模データにおけるパフォーマンス考慮点
大規模なデータセットに対して pivot_table()
を実行する場合、処理に時間がかかったり、メモリを大量に消費したりする可能性があります。データ分析において、パフォーマンスは重要な要素です。パフォーマンスを向上させるためには、以下の点を考慮してください。
- 不要な列を事前に削除: ピボットに関係のない列は、事前に DataFrame から削除することで、メモリ使用量と処理時間を削減できます。データ前処理の段階でデータ分析に必要な列のみを選択することが重要です。
- データの型を最適化: 特に文字列データが多い列は、カテゴリ型 (
category
) に変換することでメモリ効率が向上する場合があります。適切なデータ型を使用することは、大規模データのデータ集計において特に有効です。 - データ型の確認: 数値データがオブジェクト型 (
object
) になっていると計算が遅くなるため、適切な数値型 (int
,float
) に変換します。データ分析の精度と速度に影響します。 - チャンク処理: 非常に大きなデータセットの場合は、データを小さなチャンク(塊)に分割して
pivot_table()
を適用し、後で結果を結合することも有効な手段です。メモリが限られている環境でのデータ集計に役立ちます。
まとめ:Pandas pivot_table をマスターしてデータ分析を加速しよう
本記事では、Pandas ライブラリにおけるデータ再形成とデータ集計のための主要な関数である pivot()
と pivot_table()
について詳しく解説しました。これらの関数は、データ分析においてクロス集計表を作成する上で非常に重要です。
pandas.pivot()
:index
とcolumns
の組み合わせが一意であるデータに対して、シンプルなデータ再形成を行います。データ集計機能はありません。シンプルなデータ分析の初期整形に利用します。pandas.pivot_table()
:index
とcolumns
の組み合わせに重複があるデータを含む、より柔軟なデータ集計と再形成を行います。aggfunc
引数で様々な集計関数を指定できます。クロス集計表の作成や詳細なデータ分析に不可欠です。
pivot_table()
は、生のデータをデータ分析に適したクロス集計表の形式に変換するための、データ分析において非常に重要なツールです。売上データの月別・商品別集計、アンケート結果のクロス集計、各種レポート作成など、幅広い場面でその強力な機能を発揮します。データ分析の効率と質を高めるために、pivot_table()
は欠かせません。
この記事で解説した内容を参考に、ぜひあなたのデータ分析ワークフローに pivot_table()
を積極的に取り入れてみてください。実際に様々なデータに対して pivot_table()
を試すことで、さらに理解を深めることができるでしょう。データ集計とクロス集計表の作成をマスターし、データ分析を加速させましょう。

コメント