Pythonで複数シートを読み込む入門 — pandas.read_excel(sheet_name=None)
同じExcelファイルの「全シート」や「複数シート」を一気に読み込んで扱う方法を、初心者向けに丁寧に解説します。すぐ試せるコード例、よくある帳票向けテンプレート、練習問題までまとめました。
事前準備と基本の考え方
必要なライブラリ
pip install pandas openpyxl # .xlsx の読み込みに必要
# 古い .xls を読む場合は xlrd も
pip install xlrd
基本の返り値(ここがカギ)
- sheet_name=None: すべてのシートを「辞書」形式で返します。
- キーが「シート名」、値が「DataFrame」になります。
- 例:
dfs = pd.read_excel("book.xlsx", sheet_name=None)の後、dfs["Sheet1"]で1枚目のDataFrameにアクセスできます。
最小コードとすぐ使える例
すべてのシートを読み込んで、中身をざっと確認
import pandas as pd
dfs = pd.read_excel("sample.xlsx", sheet_name=None)
# シート名の一覧
print(list(dfs.keys()))
# それぞれの先頭5行を確認
for name, df in dfs.items():
print(f"--- {name} ---")
print(df.head())
Python- ポイント: まずは「シート名の一覧」を見て、どれを使うか確認します。
指定した複数シートだけ読み込む
import pandas as pd
target_sheets = ["2025_Q1", "2025_Q2"]
dfs = pd.read_excel("sales.xlsx", sheet_name=target_sheets)
# dict として返るので、必要なシートを取り出す
q1 = dfs["2025_Q1"]
q2 = dfs["2025_Q2"]
Python- ポイント: 全シートでなく「必要なシートだけ」読み込むと速く、メモリも節約できます。
よく使う引数と複数シートでのコツ
欲しい列だけ読む(usecols)
dfs = pd.read_excel("sales.xlsx", sheet_name=None, usecols=["Date", "Product", "Revenue"])
Python- 効果: 全シート共通の列だけに絞り、重たいExcelでも軽く扱えます。
先頭の説明行を飛ばす(skiprows)とヘッダー(header)
dfs = pd.read_excel("report.xlsx", sheet_name=None, skiprows=5, header=0)
Python- 前提: どのシートも同じレイアウト(5行の説明の後に表が始まる)であること。
型を安定させる(dtype、parse_dates、na_values)
dfs = pd.read_excel(
"orders.xlsx",
sheet_name=None,
dtype={"OrderID": "string", "CustomerID": "string"},
parse_dates=["OrderDate"],
na_values=["N/A", "-", "—"]
)
Python- コツ: 全シートで同じ列名・型を想定できると、後続処理が安定します。
読み込み後に“共通整形”を適用する
import pandas as pd
dfs = pd.read_excel("sales.xlsx", sheet_name=None, usecols=["Date", "Product", "Revenue"], parse_dates=["Date"])
# 全シートに同じ整形を一括適用
for name, df in dfs.items():
df["Revenue"] = pd.to_numeric(df["Revenue"], errors="coerce")
df["Product"] = df["Product"].astype("string")
Python- ポイント:「読み込み時にできること」と「読み込み後の整形」を分けて考えるとわかりやすいです。
実践テンプレート(帳票あるあるに対応)
テンプレ1:四半期シートを縦に連結して通期データにする
import pandas as pd
dfs = pd.read_excel("sales.xlsx", sheet_name=None, usecols=["Date", "Product", "Revenue"], parse_dates=["Date"])
# 例:すべてのシートを縦方向に結合
all_sales = (
pd.concat(dfs.values(), ignore_index=True)
.assign(month=lambda d: d["Date"].dt.to_period("M"))
)
# 月別の合計売上
monthly = all_sales.groupby("month", as_index=False)["Revenue"].sum()
print(monthly)
Python- 狙い: シートごとに同じ列構成なら、まず縦に1本のテーブルにしてから集計。
テンプレ2:シートごとに列名や開始行が微妙に違うときの対処
import pandas as pd
raw = pd.read_excel("report.xlsx", sheet_name=None)
normalized = {}
for name, df in raw.items():
# 1) 余分な空白を除去
df = df.rename(columns=lambda c: str(c).strip())
# 2) よく出る別名を正規化(例)
df = df.rename(columns={
"日付": "Date",
"商品名": "Product",
"金額": "Revenue",
"金額(円)": "Revenue"
})
# 3) 欠損や型を整える
if "Revenue" in df.columns:
df["Revenue"] = pd.to_numeric(df["Revenue"], errors="coerce")
normalized[name] = df
# 欲しい列が揃っているシートだけ結合
common_cols = ["Date", "Product", "Revenue"]
dfs_ready = [d[common_cols] for d in normalized.values() if set(common_cols).issubset(d.columns)]
final = pd.concat(dfs_ready, ignore_index=True)
print(final.head())
Python- 狙い: 読み込み後に“列名の統一”を挟めば、バラつく帳票でも扱いやすくなります。
テンプレ3:全シートを別々のCSVに書き出す(検証や共有に便利)
import pandas as pd
import pathlib
dfs = pd.read_excel("book.xlsx", sheet_name=None)
out_dir = pathlib.Path("export")
out_dir.mkdir(exist_ok=True)
for name, df in dfs.items():
df.to_csv(out_dir / f"{name}.csv", index=False)
Python- 狙い: まずCSV化しておくと、後から確認や差分比較が簡単。
よくあるつまずきと回避策
- 全シート同じレイアウトとは限らない
- 対策: 読み込み後に「列名の正規化」「不要列の削除」を行い、結合は“共通列が揃ったシートだけ”に絞る。
- 先頭ゼロが消える(郵便番号やコード)
- 原因: 数値として解釈される。
- 対策:
dtype={"Code": "string"}を指定。読み込み後はstr.zfill(7)などで桁を揃える。
- 日付が文字列のまま・混在
- 対策:
parse_dates=["Date"]を指定。混在時は後処理でpd.to_datetime(df["Date"], errors="coerce")。
- 対策:
- メモリがきつい
- 対策:
usecolsで列を絞る。必要なシート名だけ指定して読む。中間でCSVに逃がす。
- 対策:
- .xlsx が読めない/.xls が読めない
- 対策:
.xlsx → openpyxl、.xls → xlrdをインストール。拡張子に合ったエンジンが必要。
- 対策:
ミニ例題(手を動かして慣れる)
例題1:全シート読み込み+縦結合してトップ5商品を集計
- 課題:
sales.xlsxの全シートから「Product」「Revenue」を集めて、合計Revenueの上位5商品を出す。
import pandas as pd
dfs = pd.read_excel("sales.xlsx", sheet_name=None, usecols=["Product", "Revenue"])
all_sales = pd.concat(dfs.values(), ignore_index=True)
all_sales["Revenue"] = pd.to_numeric(all_sales["Revenue"], errors="coerce")
top5 = (
all_sales.groupby("Product", as_index=False)["Revenue"].sum()
.sort_values("Revenue", ascending=False)
.head(5)
)
print(top5)
Python例題2:シート名を「四半期」ラベルとして列に追加
- 課題:
sales.xlsxの各シート名をquarter列として保持し、後で四半期別に集計できる形にする。
import pandas as pd
dfs = pd.read_excel("sales.xlsx", sheet_name=None, usecols=["Date", "Product", "Revenue"], parse_dates=["Date"])
labeled = []
for name, df in dfs.items():
df = df.copy()
df["quarter"] = name # シート名をラベルとして付与
labeled.append(df)
final = pd.concat(labeled, ignore_index=True)
print(final.groupby("quarter", as_index=False)["Revenue"].sum())
Python例題3:レイアウトが違うシートの統一前処理
- 課題: 一部シートは「金額(円)」、一部は「Revenue」列しかない。どちらも合算して月別の売上を出す。
import pandas as pd
raw = pd.read_excel("book.xlsx", sheet_name=None)
frames = []
for name, df in raw.items():
df = df.rename(columns=lambda c: str(c).strip())
# 列の正規化
if "金額(円)" in df.columns and "Revenue" not in df.columns:
df = df.rename(columns={"金額(円)": "Revenue"})
# 必須列チェック
needed = {"Date", "Revenue"}
if needed.issubset(df.columns):
df["Revenue"] = pd.to_numeric(df["Revenue"], errors="coerce")
df["Date"] = pd.to_datetime(df["Date"], errors="coerce")
frames.append(df[["Date", "Revenue"]])
final = pd.concat(frames, ignore_index=True)
monthly = (
final.assign(month=final["Date"].dt.to_period("M"))
.groupby("month", as_index=False)["Revenue"].sum()
)
print(monthly)
Python