Pandasのpivot_tableで複数項目を選択してaggfuncで集計

※記事内に広告が含まれる場合があります。
pythonのpandasのピボットテーブル テクノロジー
スポンサーリンク

Pandasのピボットテーブルを使うと行と列を変換し、指定したグループ単位で簡単に集計(合計値、平均値、カウント数など)ができます。

エクセルのピボットテーブルはGUIベースなので操作が簡単なことにたいして、Pandasのピボットテーブルはコード指定する必要があるので明確に理解する必要があります。

私はPandasのピボットテーブルを知った時にエクセルで経験した便利機能が使えると思い喜んだのですが、Pandasピボットテーブルの記述方法は「dataframe.pivot」と「dataframe.pivot_table」の2通りあったり、コーディング時に迷うことがあったり正直難しいなと思っていました。

現在はPandasピボットテーブルを完全に習得し、思い通りに操作できるようになったので迷いやすいポイントやよく使うコード例をご紹介することで皆様が簡単にピボットテーブルを使えることを目指します。

こんな人のお役に立てます
  • ピボットテーブルの使い方が全くわからない
  • 「dataframe.pivot」と「dataframe.pivot_table」の違いが知りたい
  • よく使うピボットテーブルのパターンを知りたい
スポンサーリンク

ピボットテーブルが使えるメリット

ピボットテーブル機能があると簡易的に集計できるので少ないコードで早くアウトプットが出せますし、コードが短いがゆえに保守対応も簡単です。

例えば、ピボットテーブル機能がないSQLでピボットと同じ結果を出すには、かなり長いコードを書く必要があり現実的ではありません。

そんな便利なピボットテーブル機能を利用したことない方向けに簡単なサンプルデータとピボットテーブルの操作体験ができるサンプルコードを作成しましたのでご活用くださいませ。

dataframe.pivotとdataframe.pivot_tableの違い

Pandasのピボットテーブルにはdataframe.pivotとdataframe.pivot_tableの2つのメソッドがありますが、dataframe.pivot_tableだけ覚えれば大丈夫です。

dataframe.pivotは簡易版なので一部機能のみですがdataframe.pivot_tableは全ての機能を利用でき高度な操作や柔軟性があります。

体験用のサンプルデータを紹介

ピボットテーブルを体験できるサンプルデータを作成しましたのでダウンロードし、デスクトップ上に保存してください。

サンプルデータは私が好きなおやつを元に作成し、最初の5行を下記に表示しました。

もしpandasがインストールできない場合は過去記事のPythonライブラリのinstallはpipが簡単 エラー発生時の対応策も紹介をご覧になりインストールしてください。

import pandas as pd

df1=pd.read_csv(r"C:\Users\abi00\Desktop\sample_1.csv")

#最初の5行のみ表示
df1.head(5)
売上日大カテゴリ中カテゴリ単価売上数量売上金額商品ID商品名
2020-06-27おやつたいやき40005200000たいやきみかん
2020-01-25おやつたいやき40005200001たいやきおれんじ
2020-12-22おやつたいやき40006240002やきいもたいやき
2020-08-04おやつたいやき40007280003あんこたいやき
2020-01-22おやつたいやき4000140004栗たいやき

dataframe.pivot_tableの使い方

ピボットテーブルは表示させたい項目(列)やインデックス(行)をグループ表示させ、集計値(合計値や平均値など)を指定する機能があります。

下記にdataframe.pivot_tableの構造を示します。

DataFrame.pivot_table(index=”インデックス名”,columns=”項目名”,values=”集計したい項目名値”,margins=”小計・総計の表示有無”,aggfunc=”集計方法”)

dataframe.pivot_table(values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True)

データがアウトプットされる視点で記載してみます。

  1. columns:列にする項目を指定
  2. index:行にする項目を指定
  3. values:値として使用する列を指定 ※aggfuncを利用した集計関数として下記が存在
    ・sum:合計
    ・mean:平均
    ・max:最大
    ・min:最小
    ・count:件数
  4. margins:値をTrueにするとピボットテーブルの最後行列に合計値を表示
  5. dropna:値をTrueにすると欠損値が含まれる行や列を除外

これらのパラメータを適切に指定することで、目的に応じたピボットテーブルを作成することができます。

dataframe.pivot_tableを体験

サンプルデータでピボットテーブルを実行

それでは先ほどのサンプルデータを利用し下記パラメーターを入れたコードを実行してみましょう。

①行指定(index) → 中カテゴリ
②列指定(columns) → 大カテゴリ
③値指定(values) → ”売上数量”
④集計関数(aggfunc)→ count指定

import pandas as pd

df1=pd.read_csv(r"C:\Users\abi00\Desktop\sample_1.csv")

df1=df1.pivot_table(index="中カテゴリ", columns="大カテゴリ", values="売上数量", aggfunc = 'count')

#表示の便宜上インデックスをリセットします。
df1.reset_index()

結果をみると行と列が中カテゴリ、大カテゴリ毎に表示され集計された数量の合計値が値として格納されております。

大カテゴリ中カテゴリおやつ果物麺類
たいやき30.0NaNNaN
どら焼き31.0NaNNaN
みかんNaN31.0NaN
りんごNaN43.0NaN
パスタNaNNaN27.0
ラフランスNaN31.0NaN
ラーメンNaNNaN21.0

次に集計値をcountからsumに変えることで売上数量の合計値を表示させます。

 df1=df1.pivot_table(index="中カテゴリ", columns="大カテゴリ", values="売上数量", aggfunc = 'sum')

#表示の便宜上インデックスをリセットします。
df1.reset_index()
大カテゴリ中カテゴリおやつ果物麺類
たいやき147.0NaNNaN
どら焼き191.0NaNNaN
みかんNaN173.0NaN
りんごNaN240.0NaN
パスタNaNNaN147.0
ラフランスNaN153.0NaN
ラーメンNaNNaN111.0

「値が存在する数量」から「数量の合計値」に変わったことがわかります。

aggfuncパラメーターの使い方

集計値のNaNを除外したい場合は違う値に置き換えるオプション「fill_value=置換する値」を利用します。

df1=df1.pivot_table(index="中カテゴリ", columns="大カテゴリ", values="売上数量", aggfunc = 'sum',fill_value=0)

df1.reset_index()

これと同様の考えでaggfuncを「mean,max,min」に変更すると値も変化します。

大カテゴリ中カテゴリおやつ果物麺類
たいやき14700
どら焼き19100
みかん01730
りんご02400
パスタ00147
ラフランス01530
ラーメン00111

これと同様の考えでaggfuncを「mean,max,min」に変更すると値も変化します。

marginsパラメーターの使い方

カテゴリ毎の小計や総計を表示させることも可能でmargins=True, margins_name=’つけたい名称’とすることで表示されます。

 df1.pivot_table(index="Survived", columns="Sex", values="Fare", aggfunc = 'count', margins=True, margins_name='Total')
大カテゴリ中カテゴリおやつ果物麺類Total
たいやき14700147
どら焼き19100191
みかん01730173
りんご02400240
パスタ00147147
ラフランス01530153
ラーメン00111111
Total3385662581162

複数項目を指定する方法

今までの例は単一項目指定でしたが複数項目はlist型で指定でき[“中カテゴリ”,”売上日”]としました。

 df1.pivot_table(index=["中カテゴリ","売上日"], columns="大カテゴリ", values="売上数量", aggfunc = 'sum',fill_value=0, margins=True, margins_name='Total')
大カテゴリ中カテゴリ売上日おやつ果物麺類Total
たいやき2020-01-191001
たいやき2020-01-221001
たいやき2020-01-255005
たいやき2020-01-266006
たいやき2020-02-035005
たいやき2020-02-251001
たいやき2020-03-058008
たいやき2020-03-226006
たいやき2020-03-268008
たいやき2020-05-05100010

valuesの値をmax、minで複数表記すると

 df1.pivot_table(index=["Pclass","Survived"], columns="Sex", values="Fare", aggfunc = [max,min], margins=True, margins_name='Total')
大カテゴリ中カテゴリ売上日おやつ果物麺類Total
たいやき2020-01-191001
たいやき2020-01-221001
たいやき2020-01-255005
たいやき2020-01-266006
たいやき2020-02-035005

値を複数に指定することも可能でvalues=[“売上数量”,”売上金額”]とするコードと結果です。

中カテゴリ売上数量売上金額
大カテゴリおやつ果物麺類Totalおやつ果物麺類Total
たいやき1470014758800000588000
どら焼き191001911528000001528000
みかん017301730103800001038000
りんご024002400168000001680000
パスタ001471470026460002646000
df1.pivot_table(index=["中カテゴリ"], columns="大カテゴリ", values=["売上数量","売上金額"], aggfunc = 'sum',fill_value=0, margins=True, margins_name='Total')

pivot_table応用編

ユニーク値で集計する方法

値をユニーク化して件数を確認するにはlambdaを利用します。

df1.pivot_table(index="Survived", columns="Sex", values="Fare", margins=True, margins_name='Total', aggfunc = lambda x:len(x.unique()))
大カテゴリ中カテゴリおやつ果物麺類
たいやき8.0NaNNaN
どら焼き9.0NaNNaN
みかんNaN10.0NaN
りんごNaN10.0NaN
パスタNaNNaN7.0

ユニーク化したことでカウント数が減少しました。

複数のvalesで違う集計関数を使う方法

valuesの値をlist型にしてカンマ区切りで複数記載します。agguuncにはvaluesで指定した項目ごとの集計関数を辞書値で登録します。

df1.pivot_table(index=["中カテゴリ"], columns="大カテゴリ", values=["売上数量","売上金額"],aggfunc ={"売上数量":"count","売上金額":"sum"},fill_value=0, margins=True, margins_name='Tota
中カテゴリ売上数量売上金額
大カテゴリおやつ果物麺類Totalおやつ果物麺類Total
たいやき30003058800000588000
どら焼き3100311528000001528000
みかん0310310103800001038000
りんご0430430168000001680000
パスタ0027270026460002646000

valuesをカンマ区切りで出したい時

元データには、値が縦に並んでいるが値にすると横に並びます。

その時に、カンマなどで区切られていないと、もともとの値の境目がわからない。

この問題を解決するにはvaluesをlistとして出すことです。

df.pivot_table(index=["項目名"],values="",aggfunc = list)

上記のようにaggfuncにlistを指定することで、list式で出すことができます。

インデックスをリセットする方法

ピボットの集計結果を利用して更にデータ結合する場合はマルチインデックスになっているケースがあるのでインデックスをリセットしないと実行できないケースがあるのでやり方を説明します。

df1=df1.pivot_table(index="中カテゴリ", columns="大カテゴリ", values="売上数量", aggfunc = 'sum',fill_value=0)

df1.reset_index()

以下に具体的な例を示します

pivot_table = dataframe.pivot_table(values='値にする列名', index='行にする列名', columns='列にする列名', aggfunc='sum')
pivot_table = pivot_table.reset_index()

pandasの公式ドキュメントをご確認したいかたはこちらです。

最後に私がPythonの勉強をして入門者から中級者までにこの本1冊あれば習得できるおすすめ本記事も書いております【本1冊で】Python入門から中級までなれるおすすめ本ご興味がある方は御覧くださいませ。

その他にもPython記事を書いておりますのでご興味がある方はご覧くださいませ。

Python関連記事の一覧→テクノロジー

タイトルとURLをコピーしました