複数キーで束ねる
このレッスンでできるようになること。groupby にキーを2つ渡して、店舗とカテゴリという2軸で売上を集計できるようになります。
店舗別の合計を見ると、どの店が大きいかは分かります。しかし「渋谷店の売上は何で稼いでいるのか」までは分かりません。ここで軸をもう1本足します。groupby はリストでキーを渡すと、その組み合わせごとに束ねてくれます。
Python
by_pair = df.groupby(["店舗", "カテゴリ"])["金額"].sum()結果は店舗とカテゴリの2階建てのインデックスを持つ Series になります。これを MultiIndex と呼びます。to_dict() を掛けると、キーが ("渋谷店", "食器") のようなタプルの辞書になります。タプルは JSON にできないので、受け渡すときは "渋谷店-食器" のような文字列に組み直すか、reset_index() で普通の表に戻してから扱います。今回は文字列キーに組み直す形で練習します。
キーの順番には意味があります。["店舗", "カテゴリ"] と書けば店舗が外側、カテゴリが内側になります。「店舗ごとに、その中身をカテゴリで見る」という読み方になるので、主に見たい軸を先に書きます。逆にすると「カテゴリごとに、その内訳を店舗で見る」表になります。同じ数字でも、どちらを外側にするかで読者が受け取る主語が変わります。
SQL との対比も明確です。GROUP BY 店舗, カテゴリ と書くのと同じで、集計の粒度が細かくなるほど行数が増えます。3店舗×3カテゴリなら最大9行です。ただし実際に売れていない組み合わせは行として現れません。「渋谷店に収納の行が無い」のは売上0という意味であって、0という値が入っているわけではない点に注意してください。この空白の扱いは、次のピボットテーブルの回でもう一度出てきます。
2軸の集計ができると、比較の質が一段上がります。全店で食器が強いのか、それとも渋谷店だけが食器に偏っているのか。この違いは1軸では見えません。
要件
- groupby(["店舗", "カテゴリ"]) の形で2軸で束ねる
- キーは店舗名とカテゴリ名をハイフンでつないだ文字列にする
- 値は int() に直す
- 売上の無い組み合わせは辞書に含めない
入出力例
total_by_store_category("売上日,店舗,商品名,カテゴリ,数量,金額
2026-01-05,渋谷店,白磁のマグカップ,食器,2,3600
2026-01-08,渋谷店,木製カッティングボード,調理器具,1,4200
2026-01-09,渋谷店,白磁のマグカップ,食器,4,7200
2026-01-06,横浜店,鉄のフライパン,調理器具,1,7800
") → {"横浜店-調理器具":7800,"渋谷店-調理器具":4200,"渋谷店-食器":10800}
total_by_store_category("売上日,店舗,商品名,カテゴリ,数量,金額
2026-02-04,大宮店,積み重ね収納ボックス,収納,3,4500
2026-02-05,大宮店,布製収納バスケット,収納,2,3000
2026-02-06,横浜店,白磁のマグカップ,食器,4,7200
") → {"大宮店-収納":7500,"横浜店-食器":7200}