Python Excel操作 逆引き集 | 日付列を自動でパースする

Python Python
スポンサーリンク

なぜ「日付を自動でパースする」がそんなに大事なのか

Excelから読み込んだ日付を文字列のまま扱うと、
「月ごとに集計したい」「期間で絞り込みたい」ときに、毎回 to_datetime を書くことになります。
parse_dates=['date_col'] を使うと、読み込み時点でその列を datetime 型 にしてくれるので、
読み込んだ瞬間から .dt を使った日付操作がそのまま書けるようになります。

import pandas as pd

df = pd.read_excel(
    "sales.xlsx",
    parse_dates=["Date"]   # 「Date」列を日付型にする
)

print(df.dtypes)
print(df.head())
Python

ここで Date 列が datetime64[ns] になっていれば成功です。
これが、後の集計・フィルタリングの「土台」になります。


基本形:parse_dates=[‘date_col’] の挙動を理解する

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

import pandas as pd

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

print(df.dtypes)
Python

parse_dates=["Date"] は、「Date という列を日付として解釈してね」という指示です。
Excel側の表示が 2025/01/01 でも 2025-01-01 でも、pandasがよしなに解釈して datetime64[ns] にしてくれます。

ここで重要なのは、「読み込み後に毎回 pd.to_datetime(df['Date']) を書かなくてよくなる」ということです。
日付列があるなら、基本的に最初から parse_dates を付ける、くらいの感覚でいてOKです。

文字列として読みたい場合との違い

もし parse_dates を指定しなければ、Date 列は文字列(object)や数値として入ることがあります。
その場合、月次集計を書くときにこうなります。

df["Date"] = pd.to_datetime(df["Date"], errors="coerce")
df["month"] = df["Date"].dt.to_period("M")
Python

parse_dates を使えば、最初の to_datetime が不要になります。
「日付は日付として読む」というルールを徹底すると、コードが一段シンプルになります。


日付をパースした後にできること

月次集計を一行で書けるようになる

import pandas as pd

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

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

ここでのポイントは、df["Date"].dt.to_period("M") が素直に書けていることです。
parse_dates を忘れて文字列のままだと、まず to_datetime を挟まないと .dt が使えません。

期間での絞り込みが直感的になる

import pandas as pd

df = pd.read_excel(
    "orders.xlsx",
    parse_dates=["OrderDate"]
)

mask = (df["OrderDate"] >= "2025-01-01") & (df["OrderDate"] < "2025-04-01")
q1 = df.loc[mask]

print(q1.head())
Python

文字列のままだと、「文字列比較になってしまっておかしな結果になる」ことがありますが、
datetime 型なら、>=< がそのまま「日付としての比較」になります。


parse_dates と他の引数の組み合わせ方

dtype と一緒に使うときの考え方

dtype は「数値か文字列か」などを指定するための引数ですが、日付列は基本的に dtype ではなく parse_dates に任せます。

import pandas as pd

df = pd.read_excel(
    "sales.xlsx",
    usecols=["Date", "CustomerID", "Amount"],
    parse_dates=["Date"],
    dtype={"CustomerID": "string"}
)

print(df.dtypes)
Python

ここでは、

  • Dateparse_dates で datetime
  • CustomerIDdtype で文字列
  • Amount は自動推測(必要なら後で to_numeric

という役割分担になっています。
「日付は parse_dates、それ以外の型は dtype」という整理をしておくと迷いにくくなります。

header, names, usecols と一緒に使う

先頭に説明行があったり、列名を自分で付けたい場合でも、parse_dates は同じように使えます。

import pandas as pd

df = pd.read_excel(
    "report.xlsx",
    skiprows=4,
    header=None,
    names=["date", "item", "qty", "amount"],
    usecols=["date", "amount"],
    parse_dates=["date"]
)

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

print(df.head())
print(df.dtypes)
Python

ここでは、「Excel側の列名や位置に関係なく、自分の date 列を日付として読む」という設計になっています。
names で列名を決めてから、その名前を parse_dates に渡す、という流れです。


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

テンプレ1:売上ファイルを読み込んで月次売上を出す

import pandas as pd

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

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

このテンプレートは、「日付列をパース → 月次集計」という一番よくある流れをそのまま形にしたものです。
parse_dates を入れておくことで、df["date"].dt... が自然に書けています。

テンプレ2:注文データから特定期間の明細だけを抽出する

import pandas as pd

df = pd.read_excel(
    "orders.xlsx",
    usecols=["OrderDate", "OrderID", "CustomerID", "Amount"],
    parse_dates=["OrderDate"],
    dtype={"OrderID": "string", "CustomerID": "string"}
)

mask = (df["OrderDate"] >= "2025-01-01") & (df["OrderDate"] < "2025-02-01")
jan = df.loc[mask]

print(jan.head())
Python

ここでは、「2025年1月分だけを取り出す」という処理を、日付比較で素直に書いています。
parse_dates がないと、ここが一気に面倒になります。


つまずきやすいポイントと対処法

変な日付が混ざっていてエラーになる・NaTになる

Excel側に「日付っぽくない文字列」が混ざっていると、パースに失敗して NaT(日付版のNaN)になります。
これは悪いことではなく、「変な値がある」と教えてくれているサインです。

どうしても落としたくない場合は、読み込み後に errors="coerce" を使って自分で変換する方法もあります。

df = pd.read_excel("sales.xlsx")
df["Date"] = pd.to_datetime(df["Date"], errors="coerce")
Python

まずは parse_dates でどこまで自動でいけるか試し、ダメな場合に個別対応を考える、という順番がおすすめです。

列名の指定ミスで parse_dates が効いていない

parse_dates=["Date"] と書いたのに、実際の列名が「DATE」や「日付」だったりすると、その列はパースされません。
最初は一度 df = pd.read_excel("file.xlsx") で全部読み、print(df.columns) で正確な列名を確認してから parse_dates を書くと安全です。


小さな練習問題

練習1:sales.xlsx の Date と Amount だけを読み、月次合計を出す

条件は次の通りです。

  1. usecols=["Date", "Amount"] を使う
  2. parse_dates=["Date"] で日付型にする
  3. Amount を数値に変換する
  4. 月ごとの合計金額を計算して表示する

自分で書いてみて、df.dtypesmonthly の結果を確認してみてください。

練習2:orders.xlsx の OrderDate を日付型にして、2025年上半期だけを抽出する

条件は次の通りです。

  1. parse_dates=["OrderDate"] を使う
  2. OrderDate2025-01-01 以上、2025-07-01 未満の行だけを抽出する
  3. 抽出したDataFrameの件数と先頭5行を表示する

ここまでできると、「日付列は最初からパースしておく」という感覚がかなり身についてきます。


最後に

parse_dates=['date_col'] は、日付列に対して「最初から正しい型で受け取る」ためのスイッチです。
これを付けるかどうかで、

  • 月次集計のコードの長さ
  • 期間フィルタの書きやすさ
  • バグの入り込みやすさ

が大きく変わります。

日付が出てきたら、まず「parse_dates を付けるか?」と自分に問いかける癖をつけてみてください。
あなたのExcel処理の「時間軸の扱いやすさ」が、一段変わります。

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