「列名がない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)
Pythonheader=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=None と names=[...] をセットで使っていることです。
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行目からデータとして読みたいわけです。
そのときは、skiprows と header=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=0 と names=[...] を組み合わせます(header=None ではない点に注意)。
import pandas as pd
df = pd.read_excel(
"report.xlsx",
header=0, # 1行目をヘッダーとして読む
names=["date", "item", "qty", "amount"]
)
print(df.head())
Pythonheader=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=Noneとnames=["date", "customer", "amount"]を使うdateを日付型に、amountを数値型に変換する
自分でコードを書いてみて、df.info() で型が想定通りになっているか確認してみてください。
練習2:先頭2行が説明文、3行目からデータが始まる report.xlsx を正しく読む
条件は次の通りです。
- 1〜2行目は説明文で無視したい
- 3行目から「日付, 商品名, 数量, 金額」のデータが並んでいる
skiprowsとheader=Noneとnamesを組み合わせて読み込む- 数量と金額を数値化して、合計を出す
ここまでできると、「列名がない」「ヘッダー行がずれている」Excelに対して、かなり自信を持って対応できるようになります。
最後に
header=None は、「pandasの自動ヘッダー解釈に任せない」という宣言です。
これを使いこなせるようになると、
- 列名がない
- 列名が信用できない
- ヘッダー行がどこかよくわからない
といった、現場あるあるなExcelに対して、自分のルールでデータを受け取れるようになります。
大事なのは、
- 本当にヘッダーがないのか
- ヘッダーはあるが無視したいのか
- ヘッダーはあるが名前を変えたいのか
この3つを意識して、header=None / header=0 / names / skiprows を組み合わせることです。
