Pythonで旧形式xlsファイルを読む入門 — engine=’xlrd’(環境要確認)
古いExcel形式(.xls)をpandasで読むには、読み取りエンジンとして xlrd の利用が基本です。拡張子と環境により挙動が変わるため、初心者向けに安全な手順とコードテンプレート、つまずき対策をまとめます。
事前準備と要点
- .xls は xlrd で読む: .xlsx は xlrd 非対応。新形式は openpyxl を使う(別途)。
- インストール:
pip install xlrd - 環境確認: インストール後に簡単な読み込みが成功するか試す。失敗時は拡張子誤り(実体が .xlsx など)やファイル破損を疑う。
基本の使い方(最小コード)
import pandas as pd
# 旧形式 .xls を読む
df = pd.read_excel("legacy.xls", engine="xlrd")
print(df.head()) # 先頭5行
print(df.info()) # 列名・型・欠損
Python- ポイント: engine を明示することで「どのライブラリで読むか」を固定し、環境差による誤動作を避けられます。
よく使う引数とテンプレート
シートを指定する(sheet_name)
import pandas as pd
# 名前で指定
df = pd.read_excel("legacy.xls", sheet_name="明細", engine="xlrd")
# 先頭シート(番号で指定)
df0 = pd.read_excel("legacy.xls", sheet_name=0, engine="xlrd")
Python欲しい列だけ読む(usecols)
# 列名で指定
df = pd.read_excel("legacy.xls", engine="xlrd", usecols=["Date", "Product", "Amount"])
# A〜D列の範囲指定
df = pd.read_excel("legacy.xls", engine="xlrd", usecols="A:D")
Pythonタイトル行を飛ばす(skiprows)とヘッダー行(header)
df = pd.read_excel("legacy.xls", engine="xlrd", skiprows=5, header=0)
Pythonインデックス列を指定(index_col)
df = pd.read_excel("legacy.xls", engine="xlrd", index_col=0)
Python型指定(dtype)と日付パース(parse_dates)
df = pd.read_excel(
"legacy.xls",
engine="xlrd",
dtype={"OrderID": "string", "Qty": "Int64"}, # 先頭ゼロ保持・欠損に強い整数
parse_dates=["OrderDate"] # 日付は自動で datetime へ
)
Python実践テンプレート(帳票あるある)
テンプレ1:説明行を飛ばし、列を絞って読み、数値化
import pandas as pd
df = pd.read_excel(
"legacy.xls",
engine="xlrd",
skiprows=6, # 7行目から表
header=0,
usecols="B:G"
)
df = df.rename(columns=lambda c: str(c).strip())
# 数値列を安全に変換
for col in ["数量", "金額"]:
if col in df.columns:
df[col] = pd.to_numeric(df[col], errors="coerce")
print(df.head())
Pythonテンプレ2:コード列は文字列固定+日付パースして月次集計
import pandas as pd
df = pd.read_excel(
"legacy.xls",
engine="xlrd",
usecols=["OrderID", "OrderDate", "Amount"],
dtype={"OrderID": "string"},
parse_dates=["OrderDate"]
)
df["Amount"] = pd.to_numeric(df["Amount"], errors="coerce")
monthly = (
df.assign(month=df["OrderDate"].dt.to_period("M"))
.groupby("month", as_index=False)["Amount"].sum()
)
print(monthly)
Pythonテンプレ3:列名がない → 自分で付ける
import pandas as pd
df = pd.read_excel(
"legacy.xls",
engine="xlrd",
header=None,
names=["date", "item", "qty", "price"],
nrows=100 # まずは一部だけ確認
)
print(df.info())
Pythonつまずきやすいポイントと回避策
- 拡張子が .xls でも中身が .xlsx:
- 対策: Excelで開いて「別名保存(.xlsx)」、または
pd.read_excel(file, engine="openpyxl")を試す。
- 対策: Excelで開いて「別名保存(.xlsx)」、または
- xlrd 未インストール/古い環境:
- 対策:
pip install xlrdを実行。仮想環境での実行を推奨。
- 対策:
- 先頭ゼロが消える(郵便番号・コード):
- 対策:
dtype={"ZipCode":"string"}で文字列固定。必要に応じてstr.zfill(...)で桁揃え。
- 対策:
- 日付が文字列のまま/混在:
- 対策:
parse_dates=["Date"]を指定。失敗時は後処理でpd.to_datetime(df["Date"], errors="coerce")。
- 対策:
- 表が途中から始まる/結合セルでズレる:
- 対策:
skiprowsとusecolsを組み合わせ、見出し行を正しく合わせる。列名の空白はrename(...strip())で除去。
- 対策:
- 大きい .xls で重い:
- 対策: 列を絞る(
usecols)、最初はnrowsで部分確認、最終的には CSV に変換してから処理すると速い。
- 対策: 列を絞る(
ミニ例題(練習用)
- 例題1:.xls を xlrd 指定で読み、先頭10行表示
import pandas as pd
df = pd.read_excel("legacy.xls", engine="xlrd")
print(df.head(10))
Python- 例題2:説明行スキップ+範囲指定で読み、数値化して合計
import pandas as pd
df = pd.read_excel("legacy.xls", engine="xlrd", skiprows=4, usecols="B:E", header=0)
df["Amount"] = pd.to_numeric(df["Amount"], errors="coerce")
print("合計:", df["Amount"].sum())
Python- 例題3:コード列を文字列固定+日付パースしてフィルタ
import pandas as pd
df = pd.read_excel("legacy.xls", engine="xlrd", dtype={"OrderID": "string"}, parse_dates=["OrderDate"])
mask = (df["OrderDate"] >= "2025-01-01") & (df["OrderDate"] < "2025-07-01")
print(df.loc[mask].head())
Python