いいですね!ここでは 標準ライブラリ(csv + pathlib + collections + datetime)だけ を使って、CSVを「商品ごと × 日付ごと」にクロス集計する実践例を紹介します。
想定データ(sales.csv)
日付,商品,数量,金額
2025-11-01,りんご,10,3000
2025-11-01,みかん,5,2000
2025-11-02,りんご,7,2100
2025-11-02,バナナ,4,1200
2025-11-03,みかん,12,4800
コード例:商品ごと×日付ごとのクロス集計
import csv
from pathlib import Path
from collections import defaultdict
from datetime import datetime
csv_path = Path.home() / "Documents" / "sales.csv"
# 集計用: {商品: {日付: {"数量":合計, "金額":合計}}}
summary = defaultdict(lambda: defaultdict(lambda: {"数量": 0, "金額": 0}))
with csv_path.open("r", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
date = datetime.strptime(row["日付"], "%Y-%m-%d").date()
product = row["商品"]
qty = int(row["数量"])
price = int(row["金額"])
summary[product][date]["数量"] += qty
summary[product][date]["金額"] += price
# 表示(商品ごとに日付順で出力)
for product, dates in summary.items():
print(f"=== {product} ===")
for date, data in sorted(dates.items()):
print(f"{date}: 数量={data['数量']}, 金額={data['金額']}")
Python出力例
=== りんご ===
2025-11-01: 数量=10, 金額=3000
2025-11-02: 数量=7, 金額=2100
=== みかん ===
2025-11-01: 数量=5, 金額=2000
2025-11-03: 数量=12, 金額=4800
=== バナナ ===
2025-11-02: 数量=4, 金額=1200
応用例1: クロス集計をCSVに保存(ピボット形式)
output_path = csv_path.parent / "cross_summary.csv"
# 全日付を抽出してソート
all_dates = sorted({date for dates in summary.values() for date in dates})
with output_path.open("w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
# ヘッダー行: 商品, 各日付
writer.writerow(["商品"] + [d.isoformat() for d in all_dates])
for product, dates in summary.items():
row = [product]
for d in all_dates:
row.append(dates[d]["数量"] if d in dates else 0)
writer.writerow(row)
print("クロス集計を保存しました:", output_path)
Python👉 出力CSVイメージ:
商品,2025-11-01,2025-11-02,2025-11-03
りんご,10,7,0
みかん,5,0,12
バナナ,0,4,0
まとめ
defaultdictを入れ子にして「商品 × 日付」の二次元集計が可能sorted()を使って日付順に並べ替え- 出力を「クロス集計表(ピボット形式)」にすればExcelでの分析にも便利
👉 次のステップとしては、「月ごと×商品ごとのクロス集計」や「商品ごとに売上トップの日付を抽出」などに発展させると、さらに実務的になります。

