Pandas & NumPy Academy · レッスン

日付の正しい解析

pd.to_datetimeを使って日付文字列をdatetime64に解析し、複数の形式に対応してDatetimeIndexを設定します。

レッスン 4/413 ステップ

「日付の正しい解析」はCoddyKit上の無料Pandas & NumPy Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPandas & NumPy Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Pandas & NumPy Academyコースには全4レッスンが含まれています。

日付の解析が重要な理由

日付と時刻のデータは、トランザクションのタイムスタンプ、生年月日、イベントログ、会計期間など、現実のデータセットで広く使われています。日付が文字列(object dtype)として保存されていると、期間を計算したり、月単位でリサンプリングしたり、時系列順にソートしたりできません。文字列を Pandas の datetime64 dtype に変換すると、時系列 API を十分に活用でき、時間に基づく分析が可能になります。

import pandas as pd

df = pd.DataFrame({'date': ['2024-01-15', '2024-03-20', '2024-07-04']})
print(df['date'].dtype)  # object

# You cannot do arithmetic on string dates
# df['date'] + pd.Timedelta('1 day')  # TypeError!

# After parsing:
df['date'] = pd.to_datetime(df['date'])
print(df['date'].dtype)        # datetime64[ns]
print(df['date'] + pd.Timedelta('1 day'))

pd.to_datetime() の基本

pd.to_datetime(series) は、文字列列を datetime64 に変換するための主要な関数です。形式文字列を指定しなくても、一般的な日付形式(ISO 8601、米国式日付、欧州式日付)の多くを自動的に認識できます。結果は dtype が datetime64[ns] の Series になります。これはナノ秒精度で、1677 年から 2262 年までのタイムスタンプを格納できます。

import pandas as pd

dates = pd.Series([
    '2024-01-15',
    '15/01/2024',
    'January 15, 2024',
    '2024-01-15 08:30:00'
])

parsed = pd.to_datetime(dates)
print(parsed)
# 0   2024-01-15 00:00:00
# 1   2024-01-15 00:00:00
# 2   2024-01-15 00:00:00
# 3   2024-01-15 08:30:00
print(parsed.dtype)  # datetime64[ns]

format= 引数の指定

自動推定では遅すぎたり、あいまいだったりする場合(例:'01-02-03' は 2003 年 1 月 2 日、2003 年 2 月 1 日、2001 年 2 月 3 日のいずれにも解釈できます)は、Python の strftime コードを使った正確な format 文字列を指定します。これは大幅な高速化にもつながります。大規模なデータセットでは、Pandas が複数のパターンを試す必要がなくなるため、明示的な形式指定による解析は自動推定より 10 倍高速になることがあります。

import pandas as pd

dates = pd.Series(['15/01/2024', '20/03/2024', '04/07/2024'])

# Explicit format: day/month/year
parsed = pd.to_datetime(dates, format='%d/%m/%Y')
print(parsed)
# 0   2024-01-15
# 1   2024-03-20
# 2   2024-07-04

# Common format codes:
# %Y = 4-digit year, %y = 2-digit year
# %m = month (01-12), %d = day (01-31)
# %H = hour (0-23), %M = minute, %S = second

不正な日付に対する errors='coerce'

現実のデータセットの日付列には、タイプミスや、'TBD'、'N/A'、'99/99/9999' のような仮の文字列が含まれることがよくあります。errors='coerce' を渡すと、pd.to_datetime() は解析できない値を例外にする代わりに NaT(Not a Time。datetime における NaN に相当)へ変換します。これにより、不正な日付を特定して個別に処理できます。

import pandas as pd

dates = pd.Series(['2024-01-15', 'TBD', '2024-07-04', 'N/A'])

parsed = pd.to_datetime(dates, errors='coerce')
print(parsed)
# 0   2024-01-15
# 1          NaT
# 2   2024-07-04
# 3          NaT

# Detect bad dates
print('Bad date rows:', parsed.isna().sum())  # 2

read_csv() の parse_dates

日付を解析する最も効率的なタイミングは、pd.read_csv() の parse_dates 引数を使った読み込み時です。日付として解析する列名(または列番号)のリストを渡します。これにより、読み込み後に別途処理する必要がなくなり、Pandas が C レベルの CSV 解析中に処理するため、多くの場合は高速になります。

import pandas as pd
import io

csv_data = '''order_id,order_date,ship_date
1,2024-01-15,2024-01-18
2,2024-02-20,2024-02-22
'''

df = pd.read_csv(
    io.StringIO(csv_data),
    parse_dates=['order_date', 'ship_date']
)
print(df.dtypes)
# order_id      int64
# order_date    datetime64[ns]
# ship_date     datetime64[ns]

日付要素を扱う .dt アクセサ

列の dtype が datetime64 になると、.dt アクセサによって数多くのプロパティやメソッドを利用できるようになります。.dt.year、.dt.month、.dt.day、.dt.hour、.dt.dayofweek(0=月曜日)、.dt.is_month_end などを取り出せます。これらは、時系列予測の特徴量エンジニアリングや、期間ごとのデータ集計に使用します。

import pandas as pd

df = pd.DataFrame({
    'event_time': pd.to_datetime([
        '2024-03-15 08:30:00',
        '2024-07-04 14:00:00',
        '2024-12-25 09:00:00'
    ])
})

df['year'] = df['event_time'].dt.year
df['month'] = df['event_time'].dt.month
df['day_of_week'] = df['event_time'].dt.day_name()
df['hour'] = df['event_time'].dt.hour
print(df[['year', 'month', 'day_of_week', 'hour']])

DatetimeIndex の設定

時系列分析では、日付時刻の列を DataFrame のインデックスに設定するのが一般的です。DatetimeIndex を使うと、時間に基づくスライス(df['2024']、df['2024-01':'2024-06'])、任意の頻度へのリサンプリング、Pandas の時系列 API 全体の利用が可能になります。set_index() を使うか、read_csv で index_col を指定します。

import pandas as pd

df = pd.DataFrame({
    'date': pd.to_datetime(['2024-01-01', '2024-01-02', '2024-01-03']),
    'temp': [22.5, 23.0, 21.8]
})

df = df.set_index('date')
print(df)
#             temp
# date
# 2024-01-01  22.5
# 2024-01-02  23.0
# 2024-01-03  21.8

# Time-based slicing
print(df['2024-01-02':'2024-01-03'])

複数の日付形式の処理

日付列に複数の形式が混在している場合(例:ISO 形式の日付と米国式の日付が混在している場合)、1 つの形式文字列を指定することはできません。format='mixed'(Pandas 2.0 以降)を渡して行ごとの形式検出を有効にするか、pd.to_datetime() を呼び出す前に正規表現で列を前処理し、すべての日付を 1 つの形式に統一します。

import pandas as pd

mixed_dates = pd.Series([
    '2024-01-15',
    '03/20/2024',
    '2024-07-04T10:30:00'
])

# format='mixed' handles different formats row-by-row (Pandas >= 2.0)
parsed = pd.to_datetime(mixed_dates, format='mixed')
print(parsed)
# 0   2024-01-15 00:00:00
# 1   2024-03-20 00:00:00
# 2   2024-07-04 10:30:00

タイムゾーン対応の日時

現実のタイムスタンプには、タイムゾーン情報が含まれていることがよくあります。pd.to_datetime() は UTC オフセット付きの文字列(例:'2024-01-15 08:30:00+05:30')を解析し、タイムゾーン対応の datetime64 として保存できます。すべてのタイムスタンプを共通のタイムゾーンに統一して正しく比較・計算するには、.dt.tz_convert('UTC') を使用します。

import pandas as pd

dates = pd.to_datetime(['2024-01-15 08:30:00+05:30', '2024-01-15 10:00:00-08:00'])
print(dates)
# DatetimeIndex(['2024-01-15 08:30:00+05:30', '2024-01-15 10:00:00-08:00'])

# Convert both to UTC for fair comparison
utc_dates = dates.tz_convert('UTC')
print(utc_dates)
# DatetimeIndex(['2024-01-15 03:00:00+00:00', '2024-01-15 18:00:00+00:00'])

日付の差分の計算

2 つの datetime64 列の間で算術演算を行うと、Timedelta Series が生成されます。Timedelta から日数、時間、秒数を取り出すには、.dt.days、.dt.seconds、.dt.total_seconds() プロパティを使用できます。これは、年齢、期間、または前回のイベントからの経過日数を特徴量として計算する標準的な方法です。

import pandas as pd

df = pd.DataFrame({
    'start': pd.to_datetime(['2024-01-01', '2024-03-10', '2024-06-15']),
    'end': pd.to_datetime(['2024-01-20', '2024-04-05', '2024-06-30'])
})

df['duration_days'] = (df['end'] - df['start']).dt.days
print(df[['start', 'end', 'duration_days']])
#        start        end  duration_days
# 0 2024-01-01 2024-01-20             19
# 1 2024-03-10 2024-04-05             26
# 2 2024-06-15 2024-06-30             15

日付生成のための pd.date_range()

pd.date_range(start, end, freq=) は、等間隔の日付の系列を DatetimeIndex として生成します。これは、データを再インデックスするための完全なタイムスパインを作成する際に便利です。これにより、その日にイベントがなかった場合でも、すべての暦上の期間を出力に含められます。よく使う freq の値には、'D'(日次)、'ME'(月末)、'h'(毎時)があります。

import pandas as pd

# Weekly dates for the first quarter of 2024
weekly = pd.date_range(start='2024-01-01', end='2024-03-31', freq='W')
print(weekly[:5])
# DatetimeIndex(['2024-01-07', '2024-01-14', '2024-01-21', '2024-01-28', '2024-02-04'])

# Monthly date spine
monthly = pd.date_range(start='2024-01', periods=12, freq='ME')
print(len(monthly), monthly[0], monthly[-1])
# 12 2024-01-31 2024-12-31

理解度チェック

Pandas で日付を正しく解析する方法の理解度を確認しましょう。

レッスンのまとめ

このレッスンでは、pd.to_datetime() は文字列列を datetime64 に変換すること、format= は速度と精度のために正確なパターンを指定すること、errors='coerce' は不正な日付をエラーにせず NaT に変換することを学びました。.dt アクセサでは年、月、日などの要素を取り出せます。また、DatetimeIndex を設定すると時間に基づくスライスが可能になります。次は、ベクトル化された文字列操作を行う .str アクセサについて学びます。

無料で開始

AI チューターと学ぶ Python — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
30
レッスン
120

よくある質問

「日付の正しい解析」レッスンは無料ですか?

はい。「日付の正しい解析」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Pandas & NumPy Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Pandas & NumPy Academyコースには全4レッスンが含まれています。

「日付の正しい解析」で何を学びますか?

pd.to_datetimeを使って日付文字列をdatetime64に解析し、複数の形式に対応してDatetimeIndexを設定します。 ブラウザで直接実行するハンズオンコードでPandas & NumPy Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Pandas & NumPy Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのPandas & NumPy Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「日付の正しい解析」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このPandas & NumPy Academyレッスンでコードを書いて実行できますか?

はい。すべてのPandas & NumPy Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 列のデータ型の確認
  2. astype()による型変換
  3. カテゴリ型
  4. 日付の正しい解析
← Pandas & NumPy Academyに戻る