PythonのPandasで日付を扱う方法について

Python,イメージ

AI実装検定のご案内

Pandasで日付を扱う方法は、データ分析や時系列データ処理で非常に重要です。

Pandasは日付や時間の操作をサポートするために、datetime64[ns]型とpd.Timestamp,pd.DatetimeIndexなどの便利なクラスを提供しています。

以下に詳しく解説します。

目次

日付データの型

Pandasでは日付を次のように扱います。

  • pd.Timestamp
    単一の日付や日時を表現するオブジェクト。
    例: pd.Timestamp("2025-08-23 10:30:00")
  • pd.DatetimeIndex
    日付の配列(インデックスとして使う場合によく利用)。
    例: pd.date_range("2025-01-01", periods=5, freq="D")
  • datetime64[ns]
    DataFrameの列に日付を持たせる際の内部表現。

文字列を日付に変換

文字列として読み込まれた日付をPandasで扱える形式に変換します。

import pandas as pd

# 1) 単一の文字列をTimestampに変換
t1 = pd.to_datetime("2025-08-23")
print("t1:", t1, type(t1))

# 2) 複数フォーマットの混在を一括変換(自動判別)
df = pd.DataFrame({"date_str": ["2025/08/23", "2025-08-24", "2025.08.25", "23-08-2025"]})
df["date_auto"] = pd.to_datetime(df["date_str"], dayfirst=False, errors="coerce")  # 変換失敗はNaTに
print("\n--- 自動判別 ---")
print(df)

# 3) フォーマット指定(高速・厳密)
df["date_fmt"] = pd.to_datetime(df["date_str"], format="%d-%m-%Y", errors="coerce")
print("\n--- フォーマット指定 ---")
print(df)

# 4) CSV読み込み時に日付化(実務で便利)
from io import StringIO
csv = StringIO("""date,value
2025-01-01,100
2025-01-02,200
2025-01-15,150
2025-02-01,300
""")
df_csv = pd.read_csv(csv, parse_dates=["date"])
print("\n--- CSV parse_dates ---")
print(df_csv.dtypes)
print(df_csv)

日付の生成

pd.date_rangeで一連の日付を簡単に生成できます。

import pandas as pd

# 1) 日次で7件
r1 = pd.date_range("2025-01-01", periods=7, freq="D")
print("日次:", r1)

# 2) 毎月月初(Month Start)
r2 = pd.date_range("2025-01-01", periods=6, freq="MS")
print("\n月初:", r2)

# 3) 毎週月曜日
r3 = pd.date_range("2025-01-01", periods=6, freq="W-MON")
print("\n毎週月曜:", r3)

# 4) 営業日(Business Day)
r4 = pd.date_range("2025-01-01", periods=10, freq="B")
print("\n営業日(B):", r4)

日付の要素抽出

Datetime列から「年」「月」「日」「曜日」などを取り出せます。

import pandas as pd

df = pd.DataFrame({
    "date": pd.to_datetime(["2025-08-23", "2025-12-31", "2026-01-01", "2026-02-29"], errors="coerce")
})

df["year"] = df["date"].dt.year
df["month"] = df["date"].dt.month
df["day"] = df["date"].dt.day
df["weekday_num"] = df["date"].dt.weekday    # 月曜=0
df["weekday_name"] = df["date"].dt.day_name()  # 英語の曜日名
df["weekofyear"] = df["date"].dt.isocalendar().week  # ISO週番号
df["is_month_end"] = df["date"].dt.is_month_end
df["quarter"] = df["date"].dt.quarter

print(df)

日付の演算

日付の差分やシフトも簡単にできます。

import pandas as pd

df = pd.DataFrame({
    "date": pd.to_datetime(["2025-08-20", "2025-08-21", "2025-08-23", "2025-08-30"]),
    "value": [10, 15, 20, 40]
})

# 1) 差分(連続する行の差)※日付列のdiffはTimedelta、数値列のdiffは数値
df["date_diff"] = df["date"].diff()          # 前行との差(Timedelta)
df["value_diff"] = df["value"].diff()        # 前行との差(数値)

# 2) シフト(前日/翌日相当の行参照)
df["value_prev"] = df["value"].shift(1)
df["value_next"] = df["value"].shift(-1)

# 3) 日付への加算(7日後)
df["date_plus_7d"] = df["date"] + pd.Timedelta(days=7)

# 4) 時間ベースのローリング集計(7日間の合計)
#    まずDatetimeIndexを設定
ts = df.set_index("date")["value"].asfreq("D")  # 欠損日はNaNのまま
roll_sum_7d = ts.rolling("7D").sum()

print("--- 元データ ---")
print(df)
print("\n--- 7日ローリング合計(欠損日はNaN)---")
print(roll_sum_7d)

インデックスとして日付を使う

時系列データではDatetimeIndexをインデックスにするのが便利です。

import pandas as pd

# サンプルの時系列データ(日次)
idx = pd.date_range("2025-01-01", "2025-03-15", freq="D")
ts = pd.Series(range(len(idx)), index=idx)  # 値は 0,1,2,...

# 1) 部分文字列で抽出(2025年1月だけ)
jan = ts["2025-01"]
print("--- 2025年1月 ---")
print(jan.head(), " ... ", jan.tail())

# 2) 期間指定で抽出
period = ts["2025-02-10":"2025-02-20"]
print("\n--- 2025-02-10〜2025-02-20 ---")
print(period)

# 3) locで明示的に抽出
first_week = ts.loc["2025-01-01":"2025-01-07"]
print("\n--- 1/1〜1/7 ---")
print(first_week)

時間・タイムゾーン処理

時刻やタイムゾーンの操作も可能です。

import pandas as pd

# 1) タイムゾーンなしのTimestampを作成
t = pd.to_datetime("2025-08-23 12:00:00")
print("naive:", t, t.tzinfo)

# 2) Asia/Tokyoとしてローカライズ(ローカル時刻がJSTであると解釈)
t_tokyo = t.tz_localize("Asia/Tokyo")
print("tokyo:", t_tokyo, t_tokyo.tzinfo)

# 3) UTCに変換(同一瞬間の異なる表現)
t_utc = t_tokyo.tz_convert("UTC")
print("utc:", t_utc, t_utc.tzinfo)

# 4) Series/DatetimeIndexでも同様
idx = pd.date_range("2025-08-23 00:00", periods=3, freq="H")
s = pd.Series([1,2,3], index=idx)
s_tokyo = s.tz_localize("Asia/Tokyo")
s_ny = s_tokyo.tz_convert("America/New_York")
print("\n--- JST ---")
print(s_tokyo)
print("\n--- NY ---")
print(s_ny)

実用例(リサンプリング)

時系列データを日単位・月単位で集計できます。

import pandas as pd

# 日次の売上データ(穴あきも含む例)
sales = pd.Series(
    [100, 200, 150, 300],
    index=pd.to_datetime(["2025-01-01", "2025-01-02", "2025-01-15", "2025-02-01"])
)

# 1) 月次合計(M:月末締め)
monthly_sum = sales.resample("M").sum()

# 2) 週次平均(W:週末日曜日締め。W-MONで月曜締めに変更可能)
weekly_mean = sales.resample("W").mean()

# 3) 日次にアップサンプリングして前方埋め(asfreq+ffillの典型)
daily_ffill = sales.resample("D").ffill()

print("--- 原系列(日次・疎) ---")
print(sales)
print("\n--- 月次合計 ---")
print(monthly_sum)
print("\n--- 週次平均 ---")
print(weekly_mean)
print("\n--- 日次へアップ+前方埋め ---")
print(daily_ffill.head(20))

まとめ

Pandasで日付を扱う流れは以下の通りです。

  • 文字列をpd.to_datetimeで変換
  • 日付要素を.dtで抽出
  • 日付演算はTimedelta.shift()を利用
  • DatetimeIndexを使って時系列処理
  • リサンプリングで集計や頻度変換

以上、PythonのPandasで日付を扱う方法についてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次