Python Excel操作 逆引き集 | 空白列を削除しつつ読み込む

Python
スポンサーリンク

Pythonで空白列を削除しつつExcelを読み込む入門 — usecols=lambda x: x.strip() != ”

「見出しが空白の列(Unnamed列や何も書かれていない列)を読みたくない」を読み込み時点で解決する方法です。pandas.read_excelusecols に「列名を受け取って 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
Python

1. 空白列だけを除外(最小構成)

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
タイトルとURLをコピーしました