Python Excel操作 逆引き集 | 読み込み時に列名がない場合の処理

Python Python
スポンサーリンク

「列名がないExcel」をどう読むかという発想

現場のExcelには、最初の行に列名が書かれていないものが普通にあります。
例えば、いきなりこういう表から始まるパターンです。

| 2025/01/01 | りんご | 10 | 1200 | | 2025/01/02 | みかん | 5 | 800 |

この場合、pandas.read_excel は「1行目を列名だ」と勝手に解釈しようとします。
それを止めて、「全部データとして読み込んで、列名は自分で決める」のが header=None の役割です。

import pandas as pd

df = pd.read_excel("no_header.xlsx", header=None)
print(df.head())
print(df.columns)
Python

この状態だと、列名は 0, 1, 2, 3, ... のような番号になります。
ここから「自分で意味のある列名を付ける」か、「最初から names=… で指定する」か、という二択になります。


基本形:header=None で「全部データ」として読む

最小コードと挙動の確認

import pandas as pd

df = pd.read_excel("no_header.xlsx", header=None)

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

header=None を指定すると、pandas は「このファイルにはヘッダー行がない」とみなします。
その結果、1行目からすべてデータとして扱われ、列名は 0, 1, 2, ... という整数インデックスになります。

ここで大事なのは、「1行目をデータとして扱いたいのか」「1行目を列名として使いたいのか」を自分で決める、という意識です。
header=None は、「1行目も含めて全部データだ」と宣言するスイッチです。

後から列名を付けるパターン

header=None で読み込んだあとに、df.columns を書き換えて列名を付けることもできます。

import pandas as pd

df = pd.read_excel("no_header.xlsx", header=None)

df.columns = ["date", "item", "qty", "amount"]

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

このやり方は、「まず中身を見てから列名を決めたい」ときに便利です。
一方で、列数がわかっていて、列名も決め打ちできるなら、次のように読み込み時に一気に指定した方がきれいです。


読み込み時に列名を同時に付ける(header=None + names)

names で「最終形の列名」を最初から与える

import pandas as pd

df = pd.read_excel(
    "no_header.xlsx",
    header=None,
    names=["date", "item", "qty", "amount"]
)

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

ここで重要なのは、header=Nonenames=[...] をセットで使っていることです。

  • header=None
    既存のヘッダー行はない(または無視する)という宣言
  • names=[...]
    読み込んだ列に、この順番で列名を付けるという指定

この2つを組み合わせると、「Excel側の事情に振り回されず、最初から自分の都合のいい列名で受け取る」ことができます。

列数と names の長さを必ず合わせる

names の数は、読み込む列数と一致している必要があります。
列数が多い場合や、一部の列だけ欲しい場合は、usecols と組み合わせます。

import pandas as pd

df = pd.read_excel(
    "no_header.xlsx",
    header=None,
    usecols=[0, 2, 3],                 # 0,2,3列だけ読む
    names=["date", "qty", "amount"]    # 3列ぶんの名前
)

print(df.head())
Python

「列の位置で選ぶ → names で意味のある名前を付ける」という流れは、
列名が不安定な帳票(毎回微妙に名前が違うなど)に対して非常に強いパターンです。


「実はヘッダーはあるが使いたくない」場合の扱い

先頭行に変な文字列が入っているパターン

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

1行目: 「売上明細 2025年」
2行目: 「出力日: 2025/01/01」
3行目: 空行
4行目: 2025/01/01, りんご, 10, 1200
5行目以降: データ続き

この場合、「ヘッダー行はない」とみなして、4行目からデータとして読みたいわけです。
そのときは、skiprowsheader=None を組み合わせます。

import pandas as pd

df = pd.read_excel(
    "report.xlsx",
    skiprows=3,                         # 4行目から読み始める
    header=None,
    names=["date", "item", "qty", "amount"]
)

print(df.head())
Python

ここでのポイントは、「Excelの先頭に何行ゴミがあるか」を一度目で確認してから、skiprows を決めることです。
header=None にしているので、4行目も含めて全部データとして扱われ、names で列名を付けています。

本当はヘッダー行があるが、別の名前にしたい場合

1行目に「日付, 商品名, 数量, 金額」と書かれているが、
コード上は date, item, qty, amount という名前で扱いたい、というケースもよくあります。

この場合は、header=0names=[...] を組み合わせます(header=None ではない点に注意)。

import pandas as pd

df = pd.read_excel(
    "report.xlsx",
    header=0,                           # 1行目をヘッダーとして読む
    names=["date", "item", "qty", "amount"]
)

print(df.head())
Python

header=None は「ヘッダーがない(使わない)」宣言なので、
「ヘッダーはあるけど名前を変えたい」場合は header=0 を使う、という切り分けが大事です。


実践テンプレートでイメージを固める

テンプレ1:列名なしシートを読み、型を整えて月次集計

import pandas as pd

df = pd.read_excel(
    "sales_no_header.xlsx",
    header=None,
    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

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

  • header=None で「全部データ」として読み込む
  • names で最初から意味のある列名を付ける
  • 日付と数値をきちんと型変換する
  • そのまま月次集計まで持っていく

という流れです。
「列名がないExcel」でも、読み込み時にここまで整えてしまえば、後は普通のDataFrameとして扱えます。

テンプレ2:列番号で選んで、取り込み時に最終形の列名にする

import pandas as pd

df = pd.read_excel(
    "mixed_no_header.xlsx",
    header=None,
    usecols=[0, 3, 5],                  # 0列:日付, 3列:数量, 5列:金額 だとわかっている前提
    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())
Python

このパターンは、「列名がない or 信用できないけど、列の位置は固定されている」帳票に対して非常に強いです。
「位置で選ぶ → 自分で名前を付ける」という発想を持っておくと、かなりのExcelが相手にできます。


小さな練習問題

練習1:列名なしの orders.xlsx を読み、date, customer, amount という列名で扱う

条件は次の通りです。

  • 先頭行からデータが入っている(列名はない)
  • 列の順番は「日付, 顧客名, 金額」
  • header=Nonenames=["date", "customer", "amount"] を使う
  • date を日付型に、amount を数値型に変換する

自分でコードを書いてみて、df.info() で型が想定通りになっているか確認してみてください。

練習2:先頭2行が説明文、3行目からデータが始まる report.xlsx を正しく読む

条件は次の通りです。

  • 1〜2行目は説明文で無視したい
  • 3行目から「日付, 商品名, 数量, 金額」のデータが並んでいる
  • skiprowsheader=Nonenames を組み合わせて読み込む
  • 数量と金額を数値化して、合計を出す

ここまでできると、「列名がない」「ヘッダー行がずれている」Excelに対して、かなり自信を持って対応できるようになります。


最後に

header=None は、「pandasの自動ヘッダー解釈に任せない」という宣言です。
これを使いこなせるようになると、

  • 列名がない
  • 列名が信用できない
  • ヘッダー行がどこかよくわからない

といった、現場あるあるなExcelに対して、自分のルールでデータを受け取れるようになります。

大事なのは、

  • 本当にヘッダーがないのか
  • ヘッダーはあるが無視したいのか
  • ヘッダーはあるが名前を変えたいのか

この3つを意識して、header=None / header=0 / names / skiprows を組み合わせることです。

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