read_csvで日付が解釈できずValueErrorになる

Prep

read_csvで日付が解釈できずValueErrorになる

作成日: 最終更新: 読了時間: 1 分

日付列を含む CSV を読み込むとき、次のようなエラーメッセージが出ることがあります。

ValueError: time data '31/12/2024 23:00' does not match format '%Y-%m-%d %H:%M'

あるいは読み込み自体はできても、日付列がオブジェクト型のままでソートや差分計算ができないこともあります。
これは 日付フォーマットの推定が失敗している、または 混在した形式が存在する ためです。


解決法 1: parse_dates と日付フォーマットを指定する #

import pandas as pd

df = pd.read_csv(
    "orders.csv",
    parse_dates=["ordered_at"],
    dayfirst=True,                   # 31/12/2024 のような形式
    infer_datetime_format=True,      # パターン推測を有効化
)

parse_dates に列名を渡すと、読み込み時に自動で datetime64 型へ変換されます。
欧州形式のように日付が先頭に来る場合は dayfirst=True を忘れずに。


解決法 2: 独自フォーマットを converters で変換する #

複数フォーマットが混在する場合は、自前の変換関数を用意します。

from datetime import datetime

def parse_datetime(value: str):
    value = value.strip()
    for fmt in ("%Y/%m/%d %H:%M", "%d-%b-%Y", "%Y%m%d"):
        try:
            return datetime.strptime(value, fmt)
        except ValueError:
            continue
    return pd.NaT  # どれにも当てはまらなければ欠損扱い

df = pd.read_csv("orders.csv", converters={"ordered_at": parse_datetime})

解決法 3: 読み込み後に to_datetime で一括処理 #

df = pd.read_csv("orders.csv")
df["ordered_at"] = pd.to_datetime(
    df["ordered_at"],
    format="%Y-%m-%d %H:%M:%S",
    errors="coerce",   # 変換できなければ NaT
    utc=True,          # タイムゾーンを統一
)

読み込み後に pd.to_datetime() を呼び出す方法もあります。
errors="coerce" を使えば、エラーを出さず強制的に欠損 (NaT) にできます。


チェックリスト #

  1. 日付列に 複数の書式 が混じっていないか
  2. 日付列に 時差情報 (UTC±) が含まれていないか
  3. 数値列と見せかけて Excel のシリアル値 が紛れ込んでいないか
  4. NaT に落としたレコードについて、後続処理でどう扱うか決めたか

参考 #