Python Excel操作 逆引き集 | 既存のExcelをDataFrameの辞書で読み込む

Python Python
スポンサーリンク

「Excel全体を一気に読む」という発想を持つ

ふつうの read_excel("file.xlsx") は、デフォルトで「最初のシートだけ」を DataFrame にします。
でも、実務の Excel は「シートごとに月別」「シートごとに店舗別」「シートごとにマスタと明細」など、複数シートで1セットになっていることが多いです。

pandas.read_excel(sheet_name=None) を使うと、
「ブック内のすべてのシート」を、シート名 → DataFrame の辞書として一気に受け取れます。

import pandas as pd

dfs = pd.read_excel("book.xlsx", sheet_name=None)
print(type(dfs))          # dict
print(dfs.keys())         # シート名の一覧
Python

ここで dfs は「辞書(dict)」になり、dfs["Sheet1"] のようにして各シートの DataFrame にアクセスします。


基本形:sheet_name=None で辞書として読む

最小コードと挙動の確認

import pandas as pd

dfs = pd.read_excel("multi_sheet.xlsx", sheet_name=None)

for sheet_name, df in dfs.items():
    print("=== シート名:", sheet_name, "===")
    print(df.head())
Python

ここで重要なのは、戻り値の型が「DataFrame」ではなく「dict(辞書)」になることです。
キーがシート名、値がそのシートの DataFrame という構造になります。

この形にしておくと、

  • シート名で DataFrame を取り出す
  • ループで全シートをまとめて処理する
  • 条件に応じて特定シートだけ使う

といったことが、かなり自然に書けるようになります。

特定シートだけ取り出す

sales_jan = dfs["2025-01"]
sales_feb = dfs["2025-02"]

print(sales_jan.head())
print(sales_feb.head())
Python

シート名がわかっているなら、辞書から普通に取り出すだけです。
「シート名がそのままキーになる」というのが、sheet_name=None の一番わかりやすい利点です。


全シートをまとめて処理するパターン

全シートを縦に結合して「1つの大きな表」にする

例えば、「各月が別シートになっている売上ファイル」を想像してください。
シート名が "2025-01", "2025-02", … のようになっているとします。

import pandas as pd

dfs = pd.read_excel("monthly_sales.xlsx", sheet_name=None)

all_list = []

for sheet_name, df in dfs.items():
    df = df.copy()
    df["sheet"] = sheet_name   # どのシートから来たかを列に残す
    all_list.append(df)

all_sales = pd.concat(all_list, ignore_index=True)

print(all_sales.head())
Python

ここでのポイントは、

  • ループで各シートの DataFrame を取り出す
  • シート名を列として埋め込んでおく(後で集計に使える)
  • pd.concat で縦に結合する

という流れです。

シートごとに月が分かれていても、最終的には「1つの大きな売上テーブル」として扱えるようになります。

シートごとに集計して結果だけをまとめる

「各シートはそのままにしておき、シート単位で集計結果だけをまとめたい」というパターンもあります。

import pandas as pd

dfs = pd.read_excel("monthly_sales.xlsx", sheet_name=None)

summary_list = []

for sheet_name, df in dfs.items():
    df = df.copy()
    df["金額"] = pd.to_numeric(df["金額"], errors="coerce")
    total = df["金額"].sum()
    summary_list.append({"sheet": sheet_name, "total_amount": total})

summary = pd.DataFrame(summary_list)
print(summary)
Python

この形にすると、「シート名ごとの合計金額一覧」が簡単に作れます。
「シート=月」「シート=店舗」「シート=部署」など、シートがそのまま集計軸になるときに非常に便利です。


他の引数と組み合わせて「最初からきれいに」読む

usecols・dtype・parse_dates を同時に使う

sheet_name=None を使っても、他の引数はそのまま使えます。
すべてのシートに同じ列構造があるなら、読み込み時点でかなり整えられます。

import pandas as pd

dfs = pd.read_excel(
    "monthly_sales.xlsx",
    sheet_name=None,
    usecols=["日付", "商品", "数量", "金額"],
    parse_dates=["日付"],
    dtype={"商品": "string"}
)

for name, df in dfs.items():
    print("=== シート:", name, "===")
    print(df.dtypes)
Python

ここでは、

  • どのシートも同じ列構造だと仮定
  • 必要な列だけ読む
  • 日付を日付型にする
  • 商品名を文字列型にする

という前提を、全シートに一括で適用しています。

特定シートだけ別扱いしたい場合

もし「このシートだけ列構造が違う」「このシートだけ無視したい」という場合は、
ループの中で条件分岐を入れます。

import pandas as pd

dfs = pd.read_excel("mixed_book.xlsx", sheet_name=None)

cleaned = {}

for name, df in dfs.items():
    if name.startswith("OLD_"):
        continue  # 古いシートはスキップ

    df = df.copy()
    if "日付" in df.columns:
        df["日付"] = pd.to_datetime(df["日付"], errors="coerce")
    cleaned[name] = df

print(cleaned.keys())
Python

「まず全部読む → ループの中でシートごとに調整する」というスタイルを覚えておくと、
構造が完全には揃っていないブックにも柔軟に対応できます。


実践テンプレート

テンプレ1:月別シートを全部読み、1つの売上テーブルにまとめる

import pandas as pd

dfs = pd.read_excel(
    "monthly_sales.xlsx",
    sheet_name=None,
    usecols=["日付", "商品", "数量", "金額"],
    parse_dates=["日付"]
)

all_list = []

for sheet_name, df in dfs.items():
    df = df.copy()
    df["month"] = sheet_name
    df["数量"] = pd.to_numeric(df["数量"], errors="coerce")
    df["金額"] = pd.to_numeric(df["金額"], errors="coerce")
    all_list.append(df)

sales_all = pd.concat(all_list, ignore_index=True)

monthly = (
    sales_all.assign(month_period=sales_all["日付"].dt.to_period("M"))
             .groupby("month_period", as_index=False)["金額"].sum()
)

print(monthly)
Python

このテンプレートは、「シートごとに月が分かれている売上ファイル」を、
「1つの大きな売上テーブル → 月次集計」に持っていく典型パターンです。

テンプレ2:マスタシートと明細シートを同時に読み、結合する

例えば、"master" シートに商品マスタ、"detail" シートに売上明細があるとします。

import pandas as pd

dfs = pd.read_excel("sales_book.xlsx", sheet_name=None)

master = dfs["master"]
detail = dfs["detail"]

master["商品コード"] = master["商品コード"].astype(str)
detail["商品コード"] = detail["商品コード"].astype(str)

merged = detail.merge(master, on="商品コード", how="left")

print(merged.head())
Python

ここでは、「ブック全体を辞書で読み → 必要なシートだけ取り出す → 結合する」という流れになっています。
sheet_name=None を使うと、「どのシートをどう組み合わせるか」をコード側で自由に設計できます。


つまずきやすいポイントと注意点

戻り値が DataFrame ではなく dict になることを忘れがち

dfs = pd.read_excel(..., sheet_name=None) のあとは、
dfs.head() のように書くとエラーになります(dfs は dict なので)。

必ず「どのシートか」を指定してから DataFrame を触ります。

df = dfs["Sheet1"]
df.head()
Python

あるいは、ループで回しながら処理します。

for name, df in dfs.items():
    ...
Python

シート名のスペルミス・全角半角に注意

シート名は文字列そのものがキーになるので、
"Sheet1""sheet1" は別物ですし、全角スペースが紛れていても別扱いです。

最初に一度 print(dfs.keys()) でシート名一覧を確認してから、
コードにハードコーディングするのがおすすめです。


小さな練習問題

練習1:monthly_sales.xlsx を sheet_name=None で読み、全シートの行数を一覧にする

条件は次の通りです。

  1. dfs = pd.read_excel("monthly_sales.xlsx", sheet_name=None) として読む
  2. ループで sheet_namelen(df) を表示する
  3. 結果を DataFrame にまとめて、「シート名」「行数」の表を作る

「辞書をループする感覚」と「シートごとの情報をまとめる感覚」を意識してみてください。

練習2:sales_book.xlsx から "master" と "detail" を取り出して結合する

条件は次の通りです。

  1. sheet_name=None で全シートを読む
  2. "master""detail" を取り出す
  3. 商品コードを文字列に揃える
  4. merge で結合し、先頭5行を表示する

ここまでできると、「Excelブック全体を辞書として扱い、必要なシートを組み合わせる」という感覚がかなり身についてきます。


最後に

pandas.read_excel(sheet_name=None) は、
「Excelブックを、シート名→DataFrame の辞書として丸ごと受け取る」ための入り口です。

これを使いこなせるようになると、

複数シートを一括処理する
シートごとに集計して一覧にする
マスタと明細を同じブックから読み分ける

といったことが、自然なコードで書けるようになります。

「このブックのシートたちを、どういう関係で扱いたいか?」
それを一度紙に書き出してから、sheet_name=None で読み込んだ辞書をどう回すか設計してみると、
Excel処理の設計力が一段上がります。

タイトルとURLをコピーしました