第 02 章「データを持つ ── JSON/CSV/YAMLで考える」の主張を裏付ける。
章のどの主張に対応するか
100 個の
.xlsxから特定列を抽出する月次作業: Excel VBA で半日。pandasでglobを使って一気に処理すれば 30 秒。
(章本文「実例: 数字で見る」より)
実際にやってみると 0.07 秒(CSV)/ 1.2 秒(.xlsx 直)。
30 秒どころか、100 倍以上速い。詳細は results.md。
やること
- 入力を作る: 100 店舗 × 1 ヶ月分の売上 Excel を生成(計 10,000 行)
- 罫線、ヘッダ太字、列幅指定 ── 普通の業務 Excel に近い体裁
- CSV に変換する: pandas で 100 ファイルを
.csvに - 集計する:
pd.concat + groupbyで商品別売上ランキング(.xlsx 版と CSV 版) - 検索する:
awkで 100 ファイルから「キャベツ」だけを瞬時に抽出
全部 make all で動く。
構成
example-1/
├── README.md ── このファイル
├── generate_sales.py ── 100 店舗ぶんの .xlsx を生成
├── aggregate.py ── pandas で 100 ファイルを集計
├── Makefile ── 全工程
├── results.md ── 実測値
├── xlsx/ ── 入力 (100 ファイル, 約 824 KB)
├── csv/ ── 変換結果 (100 ファイル, 約 380 KB)
└── out/
├── size-ratio.txt
├── aggregate.log ── 商品別ランキングの実行ログ
├── summary.json ── プログラム可読の集計結果
└── cabbage.csv ── awk で抽出したキャベツ全件 (817 行)
実行
pip install openpyxl pandas
make clean && make all
合計 数秒で完了する。
なぜこれが「実例」になるのか
業務 Excel の月次集計を 1 つずつ開いて手作業でやれば、本当に半日かかる。 マウスでセルを選び、Sum を打ち、コピーして別シートに貼る、これを 100 回。 ピボットテーブルで頑張っても、再現性が無い ── 来月また同じ操作を繰り返す。
CSV にしてしまえば、groupby 1 行で終わる。同じスクリプトを来月も
そのまま使える。来年も使える。人間が二度同じ作業をしない。
しかも CSV は awk、grep、cut、sort、uniq で雑に問い合わせができる。
xlsx を grep しても文字列断片はヒットするが、行・列・型は取れない。
これが、章で言う「Excel から JSON・CSV・YAML へ。一歩で、データが 画面上の見栄えから処理できる構造に変わる」の具体形。
計測結果 — 第 02 章 example-1
実行環境: Linux 6.18 / pandas 3.0 / openpyxl 3.1 / Python 3.x
make clean && make all の出力。
サイズ比較
| 形式 | ファイル数 | 行数 | 合計バイト | KB |
|---|---|---|---|---|
Excel (.xlsx) |
100 | 10,000 | 844,010 | 824 KB |
CSV (.csv) |
100 | 10,000 | 389,606 | 380 KB |
| 比 | 2.2 倍小さい |
章本文では「4 分の 1」と書いている。今回の実演は openpyxl 生成で書式が 最小限のため 2.2 倍。Excel で人間がスタイル装飾を入れた典型的な業務ファイル では 3〜5 倍に開くことが多い。
集計時間(主目的)
100 ファイル合計 10,000 行を商品別にグループ集計する pandas コード:
df = pd.concat(pd.read_excel(f) for f in glob.glob('xlsx/*.xlsx'))
by_item = df.groupby('商品').agg(数量合計=('数量','sum'), 売上合計=('売上','sum'))
| 入力形式 | 100 ファイル読み込み + groupby |
|---|---|
.xlsx 直 (pd.read_excel) |
1.216 秒 |
.csv (pd.read_csv) |
0.071 秒 |
CSV だと 17 倍速い。100 ファイル 10,000 行を 0.07 秒で集計し、 そのまま JSON で吐き出して翌月以降も使える。
章本文の「Excel VBA で半日 = 約 4 時間 = 14,400 秒」と比べると、 約 200,000 倍速い。
集計結果(out/aggregate.log と out/summary.json)
商品別売上ランキング(CSV 版):
商品 件数 数量合計 売上合計 平均単価
トマト 792 20,367 5,189,294 254.7
ズッキーニ 868 22,375 5,023,060 225.0
レタス 845 21,674 4,446,938 205.2
キャベツ 817 20,592 3,800,898 184.8
白菜 826 20,677 3,210,809 154.8
ナス 827 21,201 3,081,172 144.8
大根 844 21,530 2,887,280 134.4
にんじん 856 20,840 2,607,918 124.5
ピーマン 853 21,892 2,518,029 115.1
玉葱 858 22,874 2,310,949 100.9
きゅうり 805 20,477 1,968,428 95.8
じゃがいも 809 20,820 1,762,066 84.4
out/summary.json:
[
{"label": "Excel ...", "files": 100, "rows": 10000, "elapsed_seconds": 1.216, ...},
{"label": "CSV ...", "files": 100, "rows": 10000, "elapsed_seconds": 0.071, ...}
]
JSON で吐き出してあるので、後段の Python やシェルで再利用できる。
awk で「キャベツ」だけ抽出
awk -F, '$3=="キャベツ"' csv/*.csv > out/cabbage.csv
- 抽出行数: 817 行
- 実行時間: 0.004 秒
100 個の .xlsx から「キャベツの行だけ取り出して」── これを Excel で
やろうとすると、フィルタ → コピー → 100 ファイル分繰り返し。awk 1 行で終わる。
トークン経済(Claude に渡す場合の参考)
| 形式 | 1 ファイル平均サイズ | 全体合計 |
|---|---|---|
.xlsx |
約 8.4 KB(ZIP+XML) | 824 KB |
.csv |
約 3.8 KB(プレーン) | 380 KB |
.json 集計結果 (summary.json) |
数百 byte | 1 ファイル |
Claude に「全月の売上集計を出して」と頼むなら、summary.json を渡せば
数百バイトで済む。元の Excel 100 ファイルを渡したらコンテキスト窓の
無駄遣い。
再現手順
pip install openpyxl pandas
make clean && make all