pandasのDataFrameでpivot_table
を使ってピボットテーブルを扱う方法について解説します。
Contents
pivot_tableによるピボットテーブルの作成
表形式のデータを扱う際に良く行われる操作としてピボットテーブルがあります。ピボットテーブルは主にExcel等の表計算やDB管理で使用される視覚化ツールです。データの分類や整理、集約といったことが効率的にできるとともに、視覚的にデータの構造を理解しやすくなります。
pandasのDataFrameではピボットテーブルを作成するためにpivot_table
という便利な関数が用意されています。本記事ではpivot_tableの基本的な使用方法を紹介します。
以降でpivot_tableの使い方を紹介するために、以下の簡単なcsvデータを用います。想定するのは企業での売上一覧データで、各製品がいつ、どこに、いくらで売られたかをまとめているものをイメージしてください。このデータを使って、製品ごと、顧客ごと等で整理したピボットテーブルを作る例を紹介していきます。
基本的なpivot_tableの使い方
上記で説明したサンプルデータ(sample.csv
)を読み込み、各製品ごとの各月売上合計となる以下のようなピボットテーブルを作ってみることを考えてみます。
DataFrameのデータに対してpivot_table
を使ってピボットテーブルを作るには以下のようにします。
【sample.csv】
no,product_code,client,date,price 1,A,顧客1,2022/03/01,1000 2,A,顧客2,2022/03/01,1000 3,B,顧客1,2022/03/01,500 4,B,顧客1,2022/03/01,500 5,C,顧客1,2022/03/01,2000 6,A,顧客2,2022/03/15,1000 7,A,顧客2,2022/03/15,1000 8,C,顧客3,2022/03/15,2000 9,B,顧客2,2022/03/31,500 10,B,顧客2,2022/03/31,500 11,B,顧客2,2022/03/31,500 12,A,顧客1,2022/04/01,1000 13,A,顧客1,2022/04/01,1000 14,B,顧客1,2022/04/01,500 15,C,顧客1,2022/04/10,2000 16,C,顧客3,2022/04/10,2000 17,C,顧客3,2022/04/10,2000 18,A,顧客1,2022/04/30,1000 19,A,顧客2,2022/04/30,1000 20,B,顧客1,2022/04/30,500
【pivot_tableの使用方法】
import pandas as pd # ===== サンプルデータの読み込み df = pd.read_csv('sample.csv') # print(df) # print(df.dtypes) # ===== データ加工 # 日付列をdatetimeに変更 df['date'] = pd.to_datetime(df['date']) # 年・月・日の列を作成 df['year'] = df['date'].dt.year df['month'] = df['date'].dt.month df['day'] = df['date'].dt.day # ===== pivot_table pt = df.pivot_table('price', index='product_code', columns='month', aggfunc='sum') print(pt)
【実行結果】 month 3 4 product_code A 4000 4000 B 2500 1000 C 4000 6000
サンプルデータ読込ではpandasのread_csv
関数を使用しています。データの内容を確認したい場合は、コメントアウトしているprintのコメントを外して確認してみてください。
年月日の情報を使用したいため、日付列をto_datetime
関数で変換した後に「年("year"
)」「月("month"
)」「日("day"
)」に該当する列情報を事前に作成しています。
ピボットテーブルを作るためにpivot_table
を使用している部分は以下の部分です。
# ===== pivot_table pt = df.pivot_table('price', index='product_code', columns='month', aggfunc='sum')
まずは集約する価格("price"
)を指定します。次にインデックス(index=
)で製品コード("product_code"
)、列(columns=
)で月("month"
)を順に指定しています。これによりピボットテーブルにおける行方向と列方向の種類が決まります。
次に指定している集約関数(aggfunc=
)では、集約するときに使用する関数を指定します。今回は合計するための"sum"
を指定しています。aggfunc
のデフォルト設定は平均("mean"
)になっていますのでaggfunc
を指定しない場合には平均が計算されます。aggfunc
には他にも"count"
、"min"
、"max"
などが指定できます。
上記のようにpivot_table
を使用することで簡単にピボットテーブルを作成することが可能です。
多重ピボットテーブル(複数レベルの指定)
上記ではシンプルなピボットテーブルの例を見てきました。今度は、複数レベルを指定して多重のピボットテーブルを作る例を見てみましょう。
具体的には、以下のように行方向は「製品コード("product_code"
)」「顧客("client"
)」の順の階層で、列方向は「年("year"
)」「月("month"
)」「日("day"
)」の順の階層で価格の合計を整理してみます。
複数レベルを指定してpivot_table
を使った多重ピボットテーブルを作るには以下のようにします。
import pandas as pd # ===== サンプルデータの読み込み df = pd.read_csv('sample.csv') # print(df) # print(df.dtypes) # ===== データ加工 # 日付列をdatetimeに変更 df['date'] = pd.to_datetime(df['date']) # 年・月・日の列を作成 df['year'] = df['date'].dt.year df['month'] = df['date'].dt.month df['day'] = df['date'].dt.day # ===== pivot_table(複数レベルでの指定) pt = df.pivot_table('price', index=['product_code', 'client'], columns=['year', 'month', 'day'], aggfunc='sum') # NaN部分を0で埋めて表示 print(pt.fillna(0))
【実行結果】 year 2022 month 3 4 day 1 15 31 1 10 30 product_code client A 顧客1 1000.0 0.0 0.0 2000.0 0.0 1000.0 顧客2 1000.0 2000.0 0.0 0.0 0.0 1000.0 B 顧客1 1000.0 0.0 0.0 500.0 0.0 500.0 顧客2 0.0 0.0 1500.0 0.0 0.0 0.0 C 顧客1 2000.0 0.0 0.0 0.0 2000.0 0.0 顧客3 0.0 2000.0 0.0 0.0 4000.0 0.0
データ加工で年・月・日等の列を事前に用意しているところは、先ほど紹介の例と同様です。ピボットテーブルを作るためにpivot_table
を使用している部分は以下の部分になります。
# ===== pivot_table(複数レベルでの指定) pt = df.pivot_table('price', index=['product_code', 'client'], columns=['year', 'month', 'day'], aggfunc='sum')
基本的な使い方は先ほどの例と同様ですが、異なるのはindex=
とcolumns=
で各階層になる列名をリストで順に指定している部分です。
このようにpivot_table
の引数の指定方法を少し変えるだけで、複数レベルの階層で集約したピボットテーブルも簡単に作ることが可能です。
[参考] groupbyでピボットテーブルを作成する方法
pivot_table
の使用方法について紹介しました。ピボットテーブルは集約の考え方を使っているためgroupby
を使用してピボットテーブルを実現することももちろん可能です。
groupby
の基本的な使い方については「DataFrameをgroupbyでグループ化して集約する方法」でまとめていますので参考にしてください。
ピボットテーブルは、groupby
での集計の多次元集計版ともいえる方法なのでgroupby
で実現できます。これまでにpivot_table
にて実現した処理と同じ動作をするgroupby
での実装例は以下のようになります。
import pandas as pd # ===== サンプルデータの読み込み df = pd.read_csv('sample.csv') # print(df) # print(df.dtypes) # ===== データ加工 # 日付列をdatetimeに変更 df['date'] = pd.to_datetime(df['date']) # 年・月・日の列を作成 df['year'] = df['date'].dt.year df['month'] = df['date'].dt.month df['day'] = df['date'].dt.day # マニュアルでpivot_tableを作成 print(df.groupby(['product_code', 'month'])['price'].sum().unstack())
【実行結果】 month 3 4 product_code A 4000 4000 B 2500 1000 C 4000 6000
ピボットテーブルを作るためにgroupby
を使った加工をしているのは以下の部分になります。
# マニュアルでpivot_tableを作成 print(df.groupby(['product_code', 'month'])['price'].sum().unstack())
この部分では、groupby
でまず製品コード("product_code"
)と月("month"
)を指定してグループを作成し、グループの中から価格("price"
)列に対してsum()
による合計を出しています。sum()
までのコードでは以下のDataFrameが出来上がっています。
product_code month A 3 4000 4 4000 B 3 2500 4 1000 C 3 4000 4 6000
このDataFrameに対してunstack()
によりmonth
列の部分を列方向に展開することでピボットテーブルの結果と同じような結果を取得しています。1行で書いてしまうと途中の処理が分からないという方は途中まででprint
表示しつつ確認してみると分かりやすいでしょう。
このようにgroupby
を使ってもピボットテーブルは作成可能です。ただし、コードは少し読みにくく、直感的には何をしているか分かりにくいと感じられるかなと思います。pivot_table
を使用する方が簡潔に処理を記載できるのでpivot_table
の使い方は是非覚えていただけるとよいかと思います。
まとめ
pandasのDataFrameでpivot_table
を使ってピボットテーブルを扱う方法について解説しました。
表形式のデータを扱う際に良く行われる操作としてピボットテーブルを使うとで他の分類や集約した状況を視覚的に確認することができます。pandasでは、pivot_table
で簡単に作成できますので、例を使って紹介しました。
また、groupbyを使ってもピボットテーブルを作成できるものの、pivot_tableの方がより簡単にピボットテーブルが作成できることを見ていただきました。
ピボットテーブルはデータの状況を確認、分析する際によく使用するツールです。pandasでも簡単に作成できますので、是非使い方を覚えてもらえればと思います。
pivot_tableの公式ドキュメントはこちらを参照してください。
上記で紹介しているソースコードについてはgithubにて公開しています。参考にしていただければと思います。