Python | データ処理:datetime 変換

Python
スポンサーリンク

概要(datetime変換は「文字列の日付を“時系列のエンジン”に乗せる最初の一歩」)

pandasで日付・時刻を扱うときは、まず文字列をdatetime型へ変換します。datetimeにしておくと、並べ替え、差分計算、月別集計、リサンプリングなど“時系列ならでは”の強い機能がすべて正しく動きます。初心者は、pd.to_datetimeでの基本変換、format指定、エラー扱い(coerce)、タイムゾーン、列が分かれている場合の組み立てを押さえると迷いません。


基本の使い方(pd.to_datetimeで文字列→日時へ)

最小例(素直なISO形式を変換する)

import pandas as pd

df = pd.DataFrame({"date": ["2025-01-01", "2025-01-02", "2025-01-03"]})
df["date"] = pd.to_datetime(df["date"])
print(df.dtypes)
# date    datetime64[ns]
Python

まずはこれ。文字列のままだと辞書順でしか並べ替えできませんが、datetimeなら時系列の昇降順や差分計算が正しく動きます。

フォーマットが混在・曖昧なときの安全策(errors=”coerce”)

df = pd.DataFrame({"date": ["2025/01/01", "2025-01-02", "bad"]})
df["date"] = pd.to_datetime(df["date"], errors="coerce")
print(df)
# 変換できない値はNaN(欠損)になる → 後でdropnaやfillnaで処理可能
Python

現実のデータはきれいじゃないことが多いです。coerceにすると“壊れた値”で落ちずに前へ進めます。

明確なフォーマットを指定して高速・正確に

df = pd.DataFrame({"date": ["01/02/2025", "12/31/2024"]})
df["date"] = pd.to_datetime(df["date"], format="%m/%d/%Y")
Python

大量データではformat指定が効率的。誤解を避け、速度も上がります。


実務でよくあるパターン(日時分割・UNIX時刻・タイムゾーン)

日付と時刻が別々の列にある

df = pd.DataFrame({
    "date": ["2025-01-01", "2025-01-02"],
    "time": ["09:30", "18:15"]
})
dt = pd.to_datetime(df["date"] + " " + df["time"])
Python

文字列結合してからto_datetimeに渡すのがシンプル。フォーマットが固定ならformatも併用できます。

UNIXエポック秒・ミリ秒からの変換

import pandas as pd

s = pd.Series([1735689600, 1735776000])  # 例: 秒
dt = pd.to_datetime(s, unit="s", utc=True).dt.tz_convert("Asia/Tokyo")
Python

unitで秒やミリ秒を指定。グローバルなデータはまずUTCにしてからローカルへtz_convertするのが定石です。

タイムゾーン付き文字列を正しく扱う

s = pd.Series(["2025-01-01T00:00:00Z", "2025-01-01T09:00:00+09:00"])
dt = pd.to_datetime(s, utc=True)           # まずUTCへ正規化
local = dt.dt.tz_convert("Asia/Tokyo")     # 表示・集計用にJSTへ
Python

タイムゾーンが混在しても、いったんUTCへ寄せると安全。比較・集計の一貫性が保てます。


時系列ならではの操作(並べ替え・差分・抽出・リサンプリング)

並べ替えと抽出の基本形

df = pd.DataFrame({
    "date": pd.to_datetime(["2025-01-02", "2024-12-31", "2025-01-01"]),
    "sales": [100, 120, 200]
})

df = df.sort_values("date")
recent = df.loc[df["date"] >= "2025-01-01"]
Python

datetimeにしておけば、範囲抽出も文字列で直感的に書けます。

差分計算(滞在時間や経過時間)

df = pd.DataFrame({
    "start": pd.to_datetime(["2025-01-01 09:00", "2025-01-01 10:00"]),
    "end":   pd.to_datetime(["2025-01-01 10:30", "2025-01-01 10:45"])
})
df["duration_min"] = (df["end"] - df["start"]).dt.total_seconds() / 60
Python

Timedeltaにしてからdt.total_secondsで必要な単位へ落とします。分・時間・日での集計が簡単です。

月別・日別に集計(resample)

daily = pd.DataFrame({
    "date": pd.to_datetime(["2025-01-01","2025-01-02","2025-01-03"]),
    "sales": [100, 120, 80]
}).set_index("date")

monthly_sum = daily.resample("M")["sales"].sum()
Python

等間隔でないデータでも、インデックスを日時にしてresampleすれば期間ごとの集計が一瞬です。


重要ポイントの深掘り(前処理順・フォーマット・欠損・型の落とし穴)

前処理の順番が品質を決める

  • 文字列のトリミングや正規化(strip/lower)を先に。
  • 曖昧なデータはerrors=”coerce”で落とし、欠損は後で扱う。
  • datetimeへ変換してから、並べ替え・フィルタ・集計を行う。

フォーマット指定の鉄則

  • formatは「必ず合う」なら積極的に使う。誤検知を避け、速度も上がる。
  • 混在フォーマットは一旦coerceで落としてから、残りを個別処理すると事故が減る。

欠損(NaT)を見逃さない

  • 変換できない値はNaTになります。countが減る、差分でエラーになるなどの原因に。
  • dropna(subset=[“date”])やfillnaでポリシーを決めてから先へ進む。

dtypeの確認とタイムゾーンの一貫性

  • date列がobjectのままになっていないか、df.dtypesで確認。
  • グローバルデータは“UTC統一→必要に応じて表示用TZ”が安全。混在TZのまま比較しない。

実践例(ログ前処理の型、JSTに揃えて日次レポート、カレンダー特徴量)

ログの時刻をUTC→JSTへ揃えて日次集計

import pandas as pd

df = pd.DataFrame({
    "ts": ["2024-12-31T15:00:00Z", "2025-01-01T01:00:00Z"],
    "value": [10, 20]
})

ts_utc = pd.to_datetime(df["ts"], utc=True)
ts_jst = ts_utc.dt.tz_convert("Asia/Tokyo")
daily = pd.DataFrame({"date": ts_jst.dt.date, "value": df["value"]})
report = daily.groupby("date", as_index=False)["value"].sum()
print(report)
Python

時差を吸収してから集計すれば、日付またぎの誤差がなくなります。

曖昧フォーマットを安全に扱う

df = pd.DataFrame({"date": ["2025-01-01", "01/02/2025", "2025.01.03", "bad"]})
df["date"] = pd.to_datetime(df["date"], errors="coerce")
clean = df.dropna(subset=["date"]).sort_values("date")
Python

まず落とし、残った“正しい日時”だけで分析を進めます。

年月日・曜日などの特徴量を追加

df = pd.DataFrame({"date": pd.to_datetime(["2025-01-01", "2025-01-02"])})
df["year"] = df["date"].dt.year
df["month"] = df["date"].dt.month
df["day"] = df["date"].dt.day
df["weekday"] = df["date"].dt.day_name()  # 例: Wednesday
Python

モデルやレポートで使いやすい派生列をdtアクセサから簡単に作れます。


まとめ(「まずto_datetime」。coerceで守り、formatで速く、TZはUTC統一が安全)

datetime変換は、時系列分析のドアです。pd.to_datetimeで文字列を日時へ変え、曖昧さはerrors=”coerce”で受け止め、確かなフォーマットにはformatを指定して速く正確に。タイムゾーンは一度UTCへ正規化してから必要なローカルへ。その上で、sort・差分・resample・dtアクセサを使えば、日次レポートも期間集計も“滑らかに”回り始めます。最初の一歩を丁寧に—そこから時系列の世界が開けます。

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