Pandas活用 pivot関数とpivot_table関数について

lecture

今回はPandasのピボットテーブルの使い方について学習します。
ピボット の使い方はその場では理解したつもりでも、なかなか使いこなせていない場合も多いと思います。
その原因はピボットの関数の使い方というよりも、そもそもピボットで何をしたいのかをきちんと理解していないためだと思います。

そしてピボットがうまく理解できないのは、そもそも縦持ちのデータ(longフォーマット)と横持ちのデータ(wideフォーマット)の違いや特徴を理解しないでピボットを使おうとするためです。
基本的にはピボットは縦持ちのデータを横持ちに変えるためのものと捉えておくと良いでしょう。

それでは、縦持ちデータと横持ちデータの違いについて説明します。

スポンサーリンク

縦持ちデータと横持ちデータの違い

縦持ちデータについて

縦持ちのデータは、カラムが固定になっている表になっているものです。データベースのテーブルなどでよく使われる方式です。
縦持ちから横持ちに変更するにはピボットを使えばよく、比較的簡単に変更できます。

横持ちデータについて

横持ちは、カラム数が可変で1行に複数のカラムをもたせているテーブルです。特徴として、分析しやすい反面データベースに保存するときには不都合です。また横持ちから縦持ちに変更するのは面倒な処理が必要なことが多いです。

ピボットを活用して横持ちに変更した例

pivot関数

縦持ちデータの項目を横持ちに変えることができます。
ただし、pivot関数を使うときのポイントは、ラベルどうし(index,columnsに指定した値)にダブリがあるとエラーになります。
これは結構起こりがちですから注意してください。

pivot関数のドキュメント

pivot関数の使い方

DataFrame.pivot(index=None, columns=None, values=None)
与えられたインデックス/列の値で編成された、再形成されたDataFrameを返します。

列の値に基づいてデータを再形成します(「ピボット」テーブルを作成します)。指定されたインデックス / 列の一意の値を使用して、結果のDataFrameの軸を形成します。この関数はデータの集約をサポートしていません。複数の値を指定すると、列にMultiIndexが発生します。再形成の詳細については、ユーザーガイドを参照してください。

パラメータ

  • index:str or object or a list of str, optional
    新しいフレームのインデックスを作成するために使用する列。Noneの場合、既存のインデックスを使用します。
    バージョン1.1.0で変更:インデックス名のリストも受け入れます。
  • columns:str or object or a list of str
    新しいフレームの列を作成するために使用する列。
    バージョン1.1.0で変更:列名のリストも受け入れます。
  • values:str, object or a list of the previous, optional
    新しいフレームの値を入力するために使用する列。指定しない場合、残りのすべての列が使用され、結果には階層的にインデックス付けされた列が含まれます。
    バージョン0.23.0で変更:列名のリストも受け入れます。

返り値

DataFrame
整形されたDataFrameを返します。

ValueErrorが出る対策
インデックス、列が複数の値を持つ組み合わせがあり、集約する必要がある場合は「DataFrame.pivot_table」を使いましょう。

pivot_table関数

pivot_tableはpivotと同様の動きをしますがこちらは集計機能が備わっています。そのため、ラベルどうし(index,columnsに指定した値)にダブリがあってもそれを集計します。デフォルトの関数はsumで、引数で指定することで変更できます。もし、文字列の値の場合はエラーになります。
pivot_table関数のドキュメント

pivot_table関数の使い方

pandas.pivot_table(data, values=None, index=None, columns=None, aggfunc=’mean’, fill_value=None, margins=False, dropna=True, margins_name=’All’, observed=False)
スプレッドシートスタイルのピボットテーブルをDataFrameとして作成します。
ピボットテーブルのレベルは、結果のDataFrameのインデックスと列のMultiIndexオブジェクト(階層インデックス)に格納されます。

Parameters

  • data:DataFrame
  • values:column to aggregate, optional
  • index:column, Grouper, array, or list of the previous
    配列が渡される場合、配列はデータと同じ長さでなければなりません。リストには他のタイプを含めることができます(リストを除く)。ピボットテーブルのインデックスでグループ化するキー。配列が渡された場合は、列の値と同じ方法で使用されます。
  • columns:column, Grouper, array, or list of the previous
    配列が渡される場合、配列はデータと同じ長さでなければなりません。リストには他のタイプを含めることができます(リストを除く)。ピボットテーブルの列でグループ化するキー。配列が渡された場合は、列の値と同じ方法で使用されます。
  • aggfunc:function, list of functions, dict, default numpy.mean
    関数のリストが渡された場合、結果のピボットテーブルには、関数名(関数オブジェクト自体から推測)がトップレベルである階層列が含まれます。dictが渡された場合、キーは集計する列であり、値は関数または関数のリストです。
  • fill_value:scalar, default None
    欠損値を置き換える値(結果のピボットテーブル、集計後)
  • margins:bool, default False
    すべての行/列を追加します(たとえば、小計/総計の場合)
  • dropna:bool, default True
    エントリがすべてNaNである列を含めないでください。
  • margins_namestr, default ‘All’
    マージンがTrueの場合に合計を含む行/列の名前。
  • observed:bool, default False
    これは、ハタのいずれかがカテゴリカルである場合にのみ適用されます。Trueの場合:カテゴリーハタの観測値のみを表示します。Falseの場合:カテゴリグループのすべての値を表示します。
    バージョン0.25.0で変更されました。

Returns

DataFrame
Excelスタイルのピボットテーブル

pivot_table関数とpivot関数の実例

次のコードはうどん屋さんのcsvデータをDataFrame形式で読み込んだとします。
CSVファイルはカレントディレクトリに置いているものとします。

udon = pd.read_csv('udon_data.csv')
udon

結果

月日 トッピング その他 麺金額 トッピング金額 その他金額 合計金額
0 8/1 うどん イカ天 NaN 300 150.0 NaN 450
1 8/1 そば たまご いなり 300 50.0 100.0 450
2 8/1 そば ちくわ天 おにぎり 300 120.0 100.0 520
3 8/1 うどん ゴボウ天 NaN 300 120.0 NaN 420
4 8/1 うどん NaN NaN 300 NaN NaN 300
5 8/2 そば たまご いなり 300 50.0 100.0 450
6 8/2 そば ちくわ天 おにぎり 300 120.0 100.0 520
7 8/2 うどん ゴボウ天 NaN 300 120.0 NaN 420
8 8/2 うどん ゴボウ天 NaN 300 120.0 NaN 420
9 8/2 うどん 鳥天 NaN 300 150.0 NaN 450
10 8/3 そば NaN いなり 300 NaN 100.0 400
11 8/3 そば NaN NaN 300 NaN NaN 300
12 8/3 そば イカ天 NaN 300 150.0 NaN 450
13 8/3 そば たまご おにぎり 300 50.0 100.0 450
14 8/3 うどん ゴボウ天 NaN 300 120.0 100.0 520
15 8/3 うどん たまご NaN 300 50.0 100.0 450
16 8/3 うどん ゴボウ天 NaN 300 120.0 NaN 420
17 8/4 うどん 鳥天 NaN 300 150.0 NaN 450
18 8/4 うどん NaN いなり 300 NaN 100.0 400
19 8/4 うどん 鳥天 いなり 300 150.0 100.0 550
20 8/4 そば NaN NaN 300 NaN NaN 300
21 8/4 そば ちくわ天 おにぎり 300 120.0 100.0 520
22 8/5 うどん ゴボウ天 NaN 300 120.0 NaN 420
23 8/5 うどん ゴボウ天 いなり 300 120.0 100.0 520
24 8/5 うどん 鳥天 NaN 300 150.0 NaN 450
25 8/5 そば NaN NaN 300 NaN NaN 300
26 8/6 うどん ゴボウ天 NaN 300 120.0 NaN 420
27 8/6 うどん 鳥天 いなり 300 150.0 100.0 550
28 8/6 そば イカ天 NaN 300 150.0 NaN 450
29 8/6 そば たまご おにぎり 300 50.0 100.0 450

pivot_table関数でindexを月日にして、columnsを麺にして合計金額の平均値をクロス集計しています。

udon.pivot_table(index='月日', columns='麺',values='合計金額')

結果

うどん そば
月日
8/1 390.000000 485.0
8/2 430.000000 485.0
8/3 463.333333 400.0
8/4 466.666667 410.0
8/5 463.333333 300.0
8/6 485.000000 450.0

次の例は、indexを月日、columnsをトッピングにクロス集計した平均値です。

udon.pivot_table(index='月日', columns='トッピング',values='合計金額')

結果

トッピング たまご ちくわ天 イカ天 ゴボウ天 鳥天
月日
8/1 450.0 520.0 450.0 420.0 NaN
8/2 450.0 520.0 NaN 420.0 450.0
8/3 450.0 NaN 450.0 470.0 NaN
8/4 NaN 520.0 NaN NaN 500.0
8/5 NaN NaN NaN 470.0 450.0
8/6 450.0 NaN 450.0 420.0 550.0

次の例はindexを麺にして、columnsをトッピングにして合計金額の合計をクロス集計しています。

udon.pivot_table(index='麺', columns='トッピング',values='合計金額',aggfunc=sum)

結果

トッピング たまご ちくわ天 イカ天 ゴボウ天 鳥天
うどん 450.0 NaN 450.0 3560.0 2450.0
そば 1800.0 1560.0 900.0 NaN NaN
タイトルとURLをコピーしました