Python Excel操作 逆引き集 | 読み込み時に先頭行をスキップする

Python Python
スポンサーリンク

なぜ「先頭行をスキップする」がこんなに大事なのか

現場のExcelは、いきなり表が始まってくれません。
会社ロゴ、レポートタイトル、出力日、担当者名、空行…そのあとにようやく「本当のデータ」が出てきます。

でも pandas.read_excel は、何も指定しないと「一番上の行をヘッダー(列名)だ」と勝手に解釈します。
その結果、タイトル行が列名になったり、データが1行ずれて入ったりして、後で必ず苦しむことになります。

そこで使うのが skiprows、特に skiprows=range(n) です。
「先頭から n 行は全部いらない。そこから下が本当の表だ」と、はっきり宣言するためのスイッチです。


基本形:skiprows=range(n) の意味をちゃんと理解する

最小コードと挙動

import pandas as pd

df = pd.read_excel(
    "report.xlsx",
    skiprows=range(3)  # 0,1,2行目(1〜3行目)をスキップ
)

print(df.head())
Python

skiprows=range(3) は、「0行目・1行目・2行目を読み飛ばす」という意味です。
Excelの見た目で言うと、「1〜3行目を無視して、4行目から読み始める」と考えてください。

ここで重要なのは、range(n) が「0 から n-1 まで」を表す、というPythonの基本ルールです。
range(5) なら 0〜4 行目(1〜5行目)をスキップします。

header と組み合わせたときのイメージ

例えば、こんな構造のシートを想像してください。

1行目: 「売上レポート 2025年」
2行目: 「出力日: 2025/01/01」
3行目: 空行
4行目: 「日付, 商品名, 数量, 金額」
5行目以降: データ

この場合、「4行目をヘッダー(列名)として使い、5行目からデータ」としたいわけです。
そのときのコードはこうなります。

df = pd.read_excel(
    "report.xlsx",
    skiprows=range(3),  # 1〜3行目を飛ばす
    header=0            # 残った先頭行(元の4行目)をヘッダーにする
)
Python

skiprows で「どこからが表か」を合わせ、header で「その行を列名として使う」と指定する。
この2つの組み合わせが、実務Excelを読むときの超重要ポイントです。


典型パターン別のテンプレート

タイトルと説明行をまとめて飛ばす

よくあるパターンは、「タイトル1行+説明2行+空行1行+表」という構造です。

import pandas as pd

df = pd.read_excel(
    "sales.xlsx",
    skiprows=range(4),  # 1〜4行目を飛ばす
    header=0            # 5行目をヘッダーとして使う
)

print(df.head())
print(df.columns)
Python

このとき、df.columns を必ず確認してください。
「想定している列名がちゃんと入っているか」「データの1行目が正しく表示されているか」を目で見るのが、トラブルを防ぐ一番の近道です。

ヘッダー行すらなく、全部データとして扱いたい場合

先頭からいきなりデータが並んでいて、列名は自分で付けたい、というパターンもあります。
さらに、その前にゴミ行がある場合はこうします。

import pandas as pd

df = pd.read_excel(
    "no_header_report.xlsx",
    skiprows=range(2),                      # 1〜2行目はゴミ
    header=None,                            # ヘッダー行はない
    names=["date", "item", "qty", "amount"] # 自分で列名を付ける
)

print(df.head())
Python

ここでは、

  • skiprows=range(2) で「3行目からが本当のデータ」と宣言
  • header=None で「その3行目も含めて全部データ」と宣言
  • names=[...] で「列名はこれを使う」と指定

という三段構えになっています。
「ヘッダーがないのか」「ヘッダーはあるが無視したいのか」で header=Noneheader=0 を使い分けるのがポイントです。

先頭 n 行だけでなく、途中の行も飛ばしたい場合

skiprows は、range(n) だけでなく、リストでも指定できます。
例えば「1〜3行目と、10行目だけ飛ばしたい」ならこうです。

df = pd.read_excel(
    "report.xlsx",
    skiprows=[0, 1, 2, 9],  # 0〜2行目と9行目をスキップ
    header=0
)
Python

ただし、まずは「先頭のゴミをまとめて飛ばす」パターンをしっかり押さえてから、
こういう細かい指定に進む方が理解がスムーズです。


skiprows と一緒にやっておきたい「型の整え方」

日付と数値を同時に整える

先頭行をスキップして表の位置を合わせたら、次は型を整えます。

import pandas as pd

df = pd.read_excel(
    "sales.xlsx",
    skiprows=range(4),
    header=0,
    usecols=["日付", "数量", "金額"],
    names=["date", "qty", "amount"],
    parse_dates=["date"]
)

df["qty"] = pd.to_numeric(df["qty"], errors="coerce")
df["amount"] = pd.to_numeric(df["amount"], errors="coerce")

print(df.head())
print(df.info())
Python

ここでやっていることは、

  • skiprows で「表の開始位置」を合わせる
  • headernames で「列名」を整える
  • parse_datesto_numeric で「型」を整える

という、読み込みの三本柱です。
skiprows はその最初の一歩で、「どこからが表か」を正しく指定できるかどうかが、後のすべてを決めます。


実践テンプレート

テンプレ1:タイトル3行+空行1行+表、という帳票を読む

import pandas as pd

df = pd.read_excel(
    "monthly_report.xlsx",
    skiprows=range(4),                      # 1〜4行目を飛ばす
    header=0,                               # 5行目をヘッダーに
    usecols=["日付", "商品名", "数量", "金額"],
    names=["date", "item", "qty", "amount"],
    parse_dates=["date"]
)

df["qty"] = pd.to_numeric(df["qty"], errors="coerce")
df["amount"] = pd.to_numeric(df["amount"], errors="coerce")

monthly = (
    df.assign(month=df["date"].dt.to_period("M"))
      .groupby("month", as_index=False)["amount"].sum()
)

print(monthly)
Python

このテンプレートは、「先頭にゴミがあるけど、表自体はきれい」という帳票にそのまま使えます。
skiprows=range(4) の「4」が、あなたのファイルでは何行になるかを確認して、そこだけ変えればOKです。

テンプレ2:先頭2行が説明、3行目からヘッダーなしデータ

import pandas as pd

df = pd.read_excel(
    "raw_data.xlsx",
    skiprows=range(2),                      # 1〜2行目を飛ばす
    header=None,                            # ヘッダーなし
    usecols=[0, 1, 3],                      # 0:日付,1:商品,3:金額
    names=["date", "item", "amount"],
    parse_dates=["date"]
)

df["amount"] = pd.to_numeric(df["amount"], errors="coerce")

print(df.head())
Python

このパターンは、「ヘッダーもないし、先頭に説明行もある」という、かなり荒れたExcelに対して有効です。
skiprowsheader=Noneusecolsnames を組み合わせることで、「自分の都合のいい形」に持ってきています。


つまずきポイントを先に潰しておく

「何行スキップすればいいか」がわからない

これは、実際にExcelを開いて「表が始まる行番号」を目で確認するのが一番早いです。
例えば「5行目から表が始まる」なら、0〜3行目をスキップしたいので skiprows=range(4) です。

Excelの行番号(1始まり)と、Pythonの行インデックス(0始まり)を頭の中で対応させてください。

1行目 → 0
2行目 → 1
3行目 → 2

n行目 → n-1

なので、「n行目から読みたい」なら skiprows=range(n-1) ではなく、range(n-1) ではなく「range(n-1)?」と一瞬迷うのではなく、
「n行目を含めて、それより上を全部飛ばす」なら range(n-1) ではなく range(n-1)…とややこしく感じたら、素直に「飛ばしたい行の0始まりインデックス」を書き出してみるといいです。
実務では、まずは skiprows=3 のように単純な数値で試し、うまくいかなければ range(3) に変える、というステップでも構いません。

(厳密には skiprows=3skiprows=range(3) は挙動が少し違うケースもありますが、先頭連続行を飛ばす用途ではほぼ同じと考えて大丈夫です。)

header と組み合わせを間違える

よくあるミスは、「skiprows で飛ばしたあと、header=None にしてしまう」パターンです。
本当は「飛ばしたあとの先頭行をヘッダーにしたい」のに、ヘッダーなしとして扱ってしまうと、列名が全部番号になってしまいます。

「飛ばしたあとの先頭行を列名にしたい」なら header=0
「飛ばしたあとの先頭行も含めて全部データにしたい」なら header=None
ここを意識して選び分けてください。


小さな練習問題

練習1:先頭3行がタイトル+説明、4行目がヘッダーの sales.xlsx を正しく読む

条件は次の通りです。

  1. skiprows=range(3) を使って、4行目から読み始める
  2. 4行目をヘッダーとして使う(header=0
  3. 「日付」「金額」列だけを usecols で読み、dateamount という列名にする
  4. date を日付型に、amount を数値型に変換する

自分でコードを書いてみて、df.head()df.info() で確認してみてください。

練習2:先頭2行がゴミ、3行目からヘッダーなしデータの raw.xlsx を整形する

条件は次の通りです。

  1. skiprows=range(2) で3行目から読み始める
  2. header=Nonenames=["date", "item", "qty", "amount"] を使う
  3. date を日付型に、qtyamount を数値型に変換する
  4. 月ごとの amount 合計を計算して表示する

ここまでできると、「先頭にどんなゴミがあっても、自分で表の開始位置を決めて読み込む」という感覚がかなり身についてきます。


最後に

skiprows=range(n) は、単なる「行スキップのオプション」ではなく、
「このExcelのどこからが本当のデータか」を自分で定義するための道具です。

先頭のゴミ行をきちんと飛ばし、ヘッダー位置を合わせてから、
usecolsnamesparse_datesdtype で一気に整える——
この流れを体に染み込ませると、どんなクセのあるExcelでも怖くなくなります。

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