Python Excel操作 逆引き集 | インデックス列として読み込む

Python Python
スポンサーリンク

「インデックスとして読む」とは何をしているのか

pandas の DataFrame には「行番号」を表すインデックスがあります。
何も指定しないと 0,1,2,3,… という単なる連番ですが、
「日付」や「ID」など、意味のある列をインデックスにしておくと、
行の指定・絞り込み・結合がぐっと書きやすくなります。

index_col=0 は、「0番目の列をインデックスとして使う」という指定です。
Excelの一番左の列を、そのまま行ラベルにするイメージです。


基本形:index_col=0 の挙動を理解する

最小コードと動きのイメージ

import pandas as pd

df = pd.read_excel("sales.xlsx", index_col=0)

print(df.head())
print(df.index)
Python

このとき、Excel の一番左の列(0番目の列)が DataFrame のインデックスになります。
つまり、その列は「普通の列」ではなくなり、df["その列名"] ではなく df.index から参照する形になります。

例えば、左端が「日付」のシートなら、読み込んだ瞬間から「日付がインデックスの DataFrame」になります。


どんな列をインデックスにすると嬉しいか

日付をインデックスにするパターン

時系列データでは、「日付をインデックス」にしておくと、期間指定が直感的に書けます。

import pandas as pd

df = pd.read_excel(
    "daily_sales.xlsx",
    parse_dates=["Date"],
    index_col="Date"   # 列名で指定する書き方
)

print(df.head())
print(df.index)
Python

この状態だと、例えばこういう書き方ができます。

# 2025年1月だけ
jan = df["2025-01-01":"2025-01-31"]

# 2025年3月以降
after_mar = df["2025-03-01":]
Python

index_col=0 ではなく index_col="Date" を使うと、
「どの列をインデックスにしているか」がコードから一目でわかるので、実務ではこちらをおすすめします。

ID・コードをインデックスにするパターン

顧客IDや商品コードなど、「行を一意に識別するキー」がある場合も、インデックスにしておくと便利です。

import pandas as pd

df = pd.read_excel(
    "customers.xlsx",
    dtype={"CustomerID": "string"},
    index_col="CustomerID"
)

print(df.head())
print(df.index)
Python

こうしておくと、特定の顧客を取り出すのが直感的になります。

customer = df.loc["C000123"]
Python

インデックスにしていない場合は、毎回 df[df["CustomerID"] == "C000123"] のように書く必要があります。
「よくキーとして使う列」は、インデックスにしておく価値が高いです。


index_col=0 と他の引数の組み合わせ

header や skiprows と一緒に使う

先頭にタイトル行などがある場合、skiprows で飛ばしてから index_col を指定します。

import pandas as pd

df = pd.read_excel(
    "report.xlsx",
    skiprows=4,              # 5行目からが表
    header=0,                # 5行目をヘッダーに
    index_col=0              # 一番左の列をインデックスに
)

print(df.head())
print(df.index)
Python

ここで大事なのは、「index_col は『ヘッダーが決まった後の列番号』で数える」ということです。
skiprowsheader の結果、どの列が 0 番目になっているかを意識してください。

usecols と一緒に使うときの注意

usecols で列を絞ると、「0番目の列」が変わります。
例えば、こういうコードを考えます。

df = pd.read_excel(
    "sales.xlsx",
    usecols=["Date", "Product", "Amount"],
    parse_dates=["Date"],
    index_col=0
)
Python

この場合、usecols で指定した中の 0 番目、つまり Date 列がインデックスになります。
「左から何番目」ではなく、「usecols で残した中の何番目」になる点に注意してください。

列名で指定すると、こういうズレを避けられます。

df = pd.read_excel(
    "sales.xlsx",
    usecols=["Date", "Product", "Amount"],
    parse_dates=["Date"],
    index_col="Date"
)
Python

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

テンプレ1:日付インデックスの売上データを読み、期間で絞り込む

import pandas as pd

df = pd.read_excel(
    "daily_sales.xlsx",
    usecols=["Date", "Amount"],
    parse_dates=["Date"],
    index_col="Date"
)

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

# 2025年1月だけ
jan = df["2025-01-01":"2025-01-31"]

# 2025年上半期
first_half = df["2025-01-01":"2025-06-30"]

print(jan.head())
print(first_half.tail())
Python

ここでは、「日付でスライスする」書き方が自然に使えています。
インデックスが単なる 0,1,2,… のままだと、こういう書き方はできません。

テンプレ2:顧客IDをインデックスにして、特定顧客の情報をすぐ引けるようにする

import pandas as pd

df = pd.read_excel(
    "customer_master.xlsx",
    dtype={"CustomerID": "string"},
    index_col="CustomerID"
)

print(df.loc["C000123"])
Python

このテンプレートは、「マスタ系の表」を扱うときに非常に便利です。
loc で一発で行を引けるので、検索や結合のコードが短くなります。


つまずきやすいポイントと注意点

インデックスに欠損や重複があると扱いづらい

インデックスは「行ラベル」なので、本来は一意であることが望ましいです。
欠損(NaN)や重複が多い列をインデックスにすると、loc での取得がややこしくなります。

「この列は本当にキーとして使えるか?」
「欠損や重複はないか?」
を一度確認してからインデックスにするのが安全です。

print(df.index.isna().sum())
print(df.index.duplicated().sum())
Python

index_col=0 を安易に使うと「意図しない列」がインデックスになる

index_col=0 は「一番左の列」をインデックスにしますが、
その列が本当にインデックスにしたい列かどうかは、ファイルごとに違います。

実務では、できるだけ列名で指定する方が安全です。

index_col="Date"
index_col="CustomerID"
Python

「左端だからインデックス」ではなく、「キーとして使いたいからインデックス」という発想で選んでください。


小さな練習問題

練習1:daily_sales.xlsx を「日付インデックス」で読み、2025年3月だけを抽出する

条件は次の通りです。

  1. usecols=["Date", "Amount"] を使う
  2. parse_dates=["Date"] で日付型にする
  3. index_col="Date" で日付をインデックスにする
  4. "2025-03-01":"2025-03-31" でスライスして表示する

自分で書いてみて、df.index の型と、抽出結果を確認してみてください。

練習2:customers.xlsx を「CustomerID インデックス」で読み、特定IDの行を取り出す

条件は次の通りです。

  1. dtype={"CustomerID": "string"} を指定する
  2. index_col="CustomerID" を指定する
  3. 任意のID(例: "C000001")の行を loc で取り出して表示する

ここまでできると、「インデックスを設計して読み込む」という感覚がかなり身についてきます。


最後に

index_col=0(あるいは index_col="列名")は、
「この表の行ラベルは何か?」を読み込み時に決めるためのスイッチです。

日付やIDのような「軸」になる列をインデックスにしておくと、

  • 期間指定やキー指定のコードが短くなる
  • 結合や検索が直感的になる
  • DataFrame の構造が「人間の感覚」に近づく

という大きなメリットがあります。

「この表の行を識別するのに、一番しっくりくる列はどれか?」
それを一度考えてから index_col を決める癖をつけると、データの扱い方が一段レベルアップします。

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