Pythonで空白列を削除しつつExcelを読み込む入門 — usecols=lambda x: x.strip() != ”
「見出しが空白の列(Unnamed列や何も書かれていない列)を読みたくない」を読み込み時点で解決する方法です。pandas.read_excel の usecols に「列名を受け取って True/False を返す関数(callable)」を渡すと、不要列をスキップできます。
基本の使い方
import pandas as pd
# 見出しが空白(""、スペースのみ)な列を除外して読み込む
df = pd.read_excel(
"report.xlsx",
usecols=lambda c: str(c).strip() != ""
)
print(df.columns)
print(df.head())
Python- 狙い: 列名が空白・スペース・改行などのみの列を読み飛ばします。
- ポイント:
usecolsの callable は「列名」を受け取ります。Trueを返した列だけ読み込みます。
よくある空白列・ダミー列の除外テンプレート
import pandas as pd
Python1. 空白列だけを除外(最小構成)
df = pd.read_excel("report.xlsx", usecols=lambda c: str(c).strip() != "")
Python- 効果: 見出しが空の列をスキップ。
2. 空白+「Unnamed: n」系を除外(Excelでよく出る)
df = pd.read_excel(
"report.xlsx",
usecols=lambda c: (str(c).strip() != "") and (not str(c).startswith("Unnamed"))
)
Python- 効果: pandasが自動命名する「Unnamed: 5」などのダミー列も除外。
3. 余分な前後スペースを無視して選ぶ(特定列だけ読み込み)
keep = {"Date", "Product", "Revenue"}
df = pd.read_excel(
"report.xlsx",
usecols=lambda c: str(c).strip() in keep
)
Python- 効果: 列名の前後スペース揺れに強く、必要列のみを確実に取得。
4. 多段ヘッダー(header=[0,1])での空列除外
df = pd.read_excel(
"multi.xlsx",
header=[0, 1],
usecols=lambda c: (
isinstance(c, tuple) and
all(str(s).strip() != "" and not str(s).startswith("Unnamed") for s in c)
)
)
Python- 効果: 複数行ヘッダーの各階層に空白・Unnamedが混ざる列をまとめて除外。
スキップや型指定と組み合わせる
import pandas as pd
df = pd.read_excel(
"monthly.xlsx",
skiprows=5, # タイトル・注記を飛ばす
header=0, # 6行目を見出しとして使う
usecols=lambda c: (str(c).strip() != "") and (not str(c).startswith("Unnamed")),
dtype={"商品コード": "string"}, # 先頭ゼロ保持
parse_dates=["日付"] # 日付列は日時型へ
)
df = df.rename(columns=lambda c: str(c).strip()) # 列名の空白をさらに除去
Python- 効果: 読み込み時点で「不要列の除外・型の安定化・日付のパース」を一気に揃えます。
読み込み後の整形ワザ(念のためのダブルチェック)
- 空白列(全欠損)を後処理で落とす:
# データがすべて欠損の列を削除
df = df.dropna(axis=1, how="all")
Python- 列名の空白や改行を一括除去:
df = df.rename(columns=lambda c: str(c).strip().replace("\n", " "))
Python- 金額列の数値化(カンマ・記号混在対策):
if "金額" in df.columns:
df["金額"] = pd.to_numeric(df["金額"].astype(str).str.replace(",", ""), errors="coerce")
Pythonつまずきやすいポイントと回避策
- 列名がない(header=None)だと callable は番号に対して評価される
- 対策: その場合は空白列の見極めが困難。いったん全列を読み、後処理で「全欠損列の削除」や「列位置での選択」に切り替えるか、
names=[...]で見出しを付与してからusecolsを使う。
- 対策: その場合は空白列の見極めが困難。いったん全列を読み、後処理で「全欠損列の削除」や「列位置での選択」に切り替えるか、
- 多段ヘッダーで空白・Unnamedが混在
- 対策: callable でタプルに対応する(上記テンプレ4)。フラット化前に除外すると後工程が楽。
- 空白ではないが実質不要な列(「備考」「予備」など)を落としたい
- 対策: 「必要列のホワイトリスト」で選ぶほうが安全。
usecols=lambda c: str(c).strip() in {...}。
- 対策: 「必要列のホワイトリスト」で選ぶほうが安全。
- 列名に全角スペースや不可視文字がある
- 対策: 読み込み後に
rename(...strip())と置換で正規化。必要ならunicodedata.normalizeを使う。
- 対策: 読み込み後に
実践テンプレート
余計な空白列・Unnamed列を除外して月次合計
import pandas as pd
df = pd.read_excel(
"sales.xlsx",
parse_dates=["Date"],
usecols=lambda c: (str(c).strip() != "") and (not str(c).startswith("Unnamed"))
)
monthly = (
df.assign(month=df["Date"].dt.to_period("M"))
.groupby("month", as_index=False)["Revenue"].sum()
)
print(monthly)
Python多段ヘッダーの「売上」ブロックだけを精査(空列除外済み)
import pandas as pd
df = pd.read_excel(
"multi_header.xlsx",
header=[0, 1],
usecols=lambda c: isinstance(c, tuple) and all(str(s).strip() != "" for s in c)
)
sales = df["売上"] # 多段ヘッダーの下位が月など
sales = sales.apply(lambda s: pd.to_numeric(s.astype(str).str.replace(",", ""), errors="coerce"))
print(sales.sum(axis=0))
Python列名に揺れがある帳票をホワイトリストで安定読み
import pandas as pd
keep = {"日付", "商品名", "数量", "金額", "Date", "Product", "Qty", "Amount"}
df = pd.read_excel(
"mixed.xlsx",
usecols=lambda c: str(c).strip() in keep,
parse_dates=["日付", "Date"]
)
Pythonミニ例題(練習用)
- 例題1: 空白列を除外して先頭10行表示
import pandas as pd
df = pd.read_excel("report.xlsx", usecols=lambda c: str(c).strip() != "")
print(df.head(10))
Python- 例題2: Unnamed列も除外して数値化・合計
import pandas as pd
df = pd.read_excel("report.xlsx", usecols=lambda c: (str(c).strip() != "") and (not str(c).startswith("Unnamed")))
df["Amount"] = pd.to_numeric(df["Amount"], errors="coerce")
print("合計:", df["Amount"].sum())
Python- 例題3: 多段ヘッダーで空白列を除外し、売上のQ1合計列を追加
import pandas as pd
df = pd.read_excel("multi.xlsx", header=[0, 1], usecols=lambda c: isinstance(c, tuple) and all(str(s).strip() != "" for s in c))
q1 = df["売上"][["1月", "2月", "3月"]].sum(axis=1)
df[("売上", "Q1合計")] = q1
print(df.head())
Python