ピボットテーブル
このレッスンでできるようになること。pivot_table を使って、店舗を縦、月を横に並べたマトリクスの集計表を作れるようになります。
前回の2軸 groupby は、結果が縦に長い形でした。3店舗×6ヶ月なら18行が縦に並びます。これは機械には読みやすい形ですが、人が見比べるには向きません。人が見るなら、店舗を行、月を列にした格子の表のほうが圧倒的に読みやすいです。この縦横の並べ替えを1行でやってくれるのが pivot_table です。
売上CSVには月の列がありません。3章で覚えたとおり、売上日を日付型にしてから月を取り出します。
ここでは図書館の貸出記録で、分館を行、月を列にした冊数の合計を例にします。売上表でも同じ考え方で軸と数値の列を選びます。
Python
loans["貸出日"] = pd.to_datetime(loans["貸出日"])
loans["月"] = loans["貸出日"].dt.month
summary = loans.pivot_table(index="分館", columns="月", values="冊数", aggfunc="sum")引数の役割ははっきり分かれています。index が縦の軸、columns が横の軸、values が集計する数値の列、aggfunc がその集計方法です。aggfunc を省くと平均になるので、合計が欲しいときは必ず "sum" を明示してください。ここは事故が多い場所です。
もう1つ気をつける点が空白です。ある店舗のある月に売上が1件も無いと、そのマスは NaN になります。売上0と欠測は本来別の意味ですが、月次の売上表では0として扱いたい場面がほとんどです。その場合は fill_value=0 を渡します。これで NaN が消え、値も整数のまま扱えます。fill_value を渡さないと列全体が float になり、合計が 15000.0 のように表示される点も覚えておいてください。
出来上がった表は DataFrame なので、そのまま返さずに to_dict() で辞書にします。pivot_table の to_dict() は列を外側、行を内側にした入れ子の辞書を返します。行を外側にしたいときは to_dict(orient="index") を使います。どちらの向きが欲しいかを決めてから書くと迷いません。
ランキングを返すときは、Series のラベルと値を別々のリストにできます。たとえばカテゴリ名をラベル、件数を値にした Series なら、index[0] は最多カテゴリ名、index.tolist() はカテゴリ名の一覧、tolist() は件数の一覧を返します。ラベルと値は同じ順で並ぶので、同じ順位どうしを対応させられます。後の出現回数のレッスンで使います。
Python
category_counts = pd.Series([3, 2], index=["調理器具", "食器"])
top_category = category_counts.index[0]
names = category_counts.index.tolist()
counts = category_counts.tolist()この表が第4章の成果物の骨格になります。次の value_counts と合わせて、月次集計表を完成させます。
演習では table を作るところに集中します。ひな形の _matrix_dict(table) は、店舗が外側になる辞書を作り、月キーを文字列、金額を Python の整数に直します。補助関数の書き直しは不要です。
要件
- 売上日を to_datetime で日付型にしてから月を取り出す
- pivot_table の index は 店舗、columns は 月、values は 金額
- aggfunc は "sum" を明示する
- 売上の無いマスは fill_value=0 で0にする
- 内側のキーは月の数字を文字列にしたもの(例 1月なら "1")にする
- table を作ったら、辞書化は準備済みの _matrix_dict に任せる