基本的にエクセルで行っているようなことは全てRなりPythonなりで対応したいと考えていますが、代表的なものとしてピボットテーブルのやり方を。
ピボットテーブルの対象となるデータの準備
まずは以下のようなデータを用意します。イメージとしては学校での部活動の人数を学年・クラス別にした表ですね。
エクセルであれば簡単でピボットテーブル処理できるのでしょうが、さてPythonでは。。。
Grade | Class | Club | Headcount |
---|---|---|---|
First | A | Soccer | 3 |
First | A | Baseball | 5 |
First | A | Tennis | 3 |
First | B | Soccer | 6 |
First | B | Baseball | 7 |
First | B | Tennis | 8 |
First | C | Soccer | 4 |
First | C | Baseball | 0 |
First | C | Tennis | 2 |
Second | A | Soccer | 6 |
Second | A | Baseball | 3 |
Second | A | Tennis | 4 |
Second | B | Soccer | 1 |
Second | B | Baseball | 8 |
Second | B | Tennis | 9 |
Second | C | Soccer | 6 |
Second | C | Baseball | 5 |
Second | C | Tennis | 7 |
Third | A | Soccer | 3 |
Third | A | Baseball | 2 |
Third | A | Tennis | 6 |
Third | B | Soccer | 7 |
Third | B | Baseball | 4 |
Third | B | Tennis | 9 |
Third | C | Soccer | 7 |
Third | C | Baseball | 8 |
Third | C | Tennis | 6 |
PythonのPandasのデータフレームでピボットテーブルの対象となるデータを準備
以下のコマンドでデータフレームを作成します。上記表をクリップボードにコピーして以下のコードを実行
import pandas as pd df = pd.read_clipboard()
クリップボードがからのコピーを避けたい場合は、どうするのが良いのかいまいちなのですが、
例えば以下のように記述可能です。
あまり綺麗ではないので、良い方法がありましたらご指摘いただけると
import pandas as pd a = ["First" if i <9 else "Second" if i < 18 else "Third" for i in range(27)] b = ["A" if 3>i%9 else "B" if 6>i%9 else "C" for i in range(27)] c = [ "Soccer" if i%3 == 0 else "Baseball" if i%3 ==1 else "Tennis" for i in range(27)] d = [3,5,3,6,7,8,4,0,2,6,3,4,1,8,9,6,5,7,3,2,6,7,4,9,7,8,6] df = pd.DataFrame({0:a, 1:b, 2:c, 3:d})#データフレームに変換 df.columns=["Grade", "Class", "Club", "Headcount"]#データフレームの列名を指定
PythonのPandasのデータフレームでピボットテーブルを作成
ピボットテーブルで和を取る
例えば、行方向にGradeを、列方向にClubをとったピボットテーブル(集計方法は和を取る)を作成するのであれば以下のコードで対応可能です。
df.pivot_table(index=["Grade"], columns=["Club"], values=["Headcount"], aggfunc="sum")
これで結果は以下のようになります。
Headcount Club Baseball Soccer Tennis Grade First 12 13 13 Second 16 13 20 Third 14 17 21
今回は集計関数をsumにしたので(aggfunc="sum")和を求めましたが、他の集計方法も可能です。(後述)
ピボットテーブルのNaNを0に変更する
NaNを0にしたい場合には
fill_value=0
を追加すれば可能です。