Pandas & NumPy Academy · レッスン

時間特徴量の抽出

.dtアクセサーを使って日時列からyear、month、day、day_of_week、hourを取り出し、特徴量を作成します。

レッスン 4/413 ステップ

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

時間特徴量を抽出する理由

生のdatetime64列は、ほとんどの機械学習アルゴリズムにとって扱いにくいものです。たとえば、2024-12-25が祝日であることや、Fridayが小売売上の増加につながることを理解できません。時間特徴量エンジニアリングでは、datetime列から年、月、日、曜日、時刻などの意味のある要素を抽出し、モデルや分析関数が直接扱える数値列またはカテゴリ列として分けます。

.dtアクセサー

DataFrameの列のdtypeがdatetime64の場合、.dtアクセサーを使って、すべてのdatetimeプロパティとメソッドにベクトル化された形でアクセスできます。行ごとにPython関数を適用する代わりに、df['date'].dt.yearと書けば、Pandasが1回の高速な処理ですべての行の年を計算します。同じアクセサーは、異なるプロパティを持つtimedelta64列にも使用できます。

import pandas as pd

df = pd.DataFrame({
    'event_date': pd.date_range('2024-01-01', periods=8, freq='D'),
    'revenue': [200, 350, 280, 310, 420, 380, 190, 260]
})

# Access datetime properties with .dt
print(df['event_date'].dt.year)    # 2024 for all
print(df['event_date'].dt.month)   # 1 for all
print(df['event_date'].dt.day[:5]) # 1, 2, 3, 4, 5

日付要素の抽出

日付要素で最もよく使われる.dtプロパティは、.dt.year、.dt.month、.dt.day、.dt.day_of_week(0=月曜日から6=日曜日)、.dt.day_of_year、.dt.weekまたは.dt.isocalendar().week、.dt.quarter、.dt.days_in_monthです。それぞれ、特徴量として直接使用できる整数のSeriesを返します。

df['year']        = df['event_date'].dt.year
df['month']       = df['event_date'].dt.month
df['day']         = df['event_date'].dt.day
df['day_of_week'] = df['event_date'].dt.day_of_week  # 0=Mon
df['quarter']     = df['event_date'].dt.quarter
df['day_of_year'] = df['event_date'].dt.day_of_year

print(df[['event_date', 'year', 'month', 'day',
           'day_of_week', 'quarter']].head())

時刻要素の抽出

日付だけでなく時刻情報も含むdatetime列には、.dt.hour、.dt.minute、.dt.second、.dt.microsecondを使います。これらは、日中の時間帯別分析、ユーザー行動のモデル化(朝と夜のパターン)、時刻が目的変数に影響するあらゆるシステムで重要です。

df_ts = pd.DataFrame({
    'timestamp': pd.date_range('2024-01-01', periods=6, freq='4h'),
    'logins': [50, 200, 320, 280, 180, 90]
})

df_ts['hour']   = df_ts['timestamp'].dt.hour
df_ts['minute'] = df_ts['timestamp'].dt.minute
df_ts['date']   = df_ts['timestamp'].dt.date    # Python date object
df_ts['time']   = df_ts['timestamp'].dt.time    # Python time object
print(df_ts[['timestamp', 'hour', 'date']].head())

曜日名と月名

人間が読みやすいラベルを取得するには、.dt.day_name()と.dt.month_name()を使います。これにより、'Monday'や'January'のような文字列名を取得できます。レポートでの表示や、曜日・月による影響を表すカテゴリ特徴量の作成に便利です。localeを渡して、他の言語の名前を取得することもできます。

df['day_name']   = df['event_date'].dt.day_name()
df['month_name'] = df['event_date'].dt.month_name()

print(df[['event_date', 'day_name', 'month_name']].head(5))
# event_date day_name month_name
# 2024-01-01   Monday    January
# 2024-01-02  Tuesday    January
# 2024-01-03  Wednesday  January

週末フラグと営業日フラグ

日付が週末に当たるかどうかを示すブール値のフラグは、非常によく使われる特徴量です。day_of_week >= 5により、土曜日(5)と日曜日(6)にTrueが返されます。より高度な営業日カレンダーの特徴量にはnumpy.busdaycalendarが祝日にも対応しますが、多くの場合は単純な平日・週末の区分で影響の大部分を捉えられます。

df['is_weekend'] = df['event_date'].dt.day_of_week >= 5
df['is_weekday'] = ~df['is_weekend']

# Compare weekend vs weekday revenue
print(df.groupby('is_weekend')['revenue'].mean().round(1))
# is_weekend
# False    308.3  <- weekday average
# True     285.0  <- weekend average

期間の開始・終了フラグ

.dtアクセサーには、日付が期間の開始または終了であるかを識別するブール値プロパティもあります。.dt.is_month_start、.dt.is_month_end、.dt.is_quarter_start、.dt.is_quarter_end、.dt.is_year_start、.dt.is_year_endなどです。これらは、報告期間、請求サイクル、季節の境界による影響を検出するのに便利です。

dates_series = pd.Series(
    pd.date_range('2024-01-28', periods=10, freq='D')
)

print(dates_series[dates_series.dt.is_month_start].values)
# ['2024-02-01']

print(dates_series[dates_series.dt.is_month_end].values)
# ['2024-01-31']

時間特徴量の周期性エンコーディング

月と時刻は周期的です。12月(12)は1月(1)に近く、23:00は00:00に近い値です。これらを線形な整数(1~12または0~23)として扱うと、ほとんどのモデルに誤った情報を与えてしまいます。周期的な特徴量は、サインとコサインの変換を使ってエンコードします。式はsin(2π × value / max_value)とcos(2π × value / max_value)です。これにより、モデルが正しく利用できるよう、円環構造を2つの数値列に埋め込めます。

import numpy as np

# Cyclical encoding for month (1-12)
df['month_sin'] = np.sin(2 * np.pi * df['month'] / 12)
df['month_cos'] = np.cos(2 * np.pi * df['month'] / 12)

# Cyclical encoding for day of week (0-6)
df['dow_sin'] = np.sin(2 * np.pi * df['day_of_week'] / 7)
df['dow_cos'] = np.cos(2 * np.pi * df['day_of_week'] / 7)

print(df[['month', 'month_sin', 'month_cos']].head().round(3))

Timedeltaの算術演算

2つのdatetime列を減算すると、timedelta64のSeriesが生成されます。timedeltaのSeriesに対する.dtアクセサーでは、.dt.days、.dt.seconds、.dt.total_seconds()を利用できます。これにより、イベントの継続時間、前回の購入からの経過時間、日数単位の経過年数などを、さらなる分析に使える数値列として計算できます。

df_orders = pd.DataFrame({
    'order_date':    pd.to_datetime(['2024-01-01', '2024-02-10', '2024-03-05']),
    'delivery_date': pd.to_datetime(['2024-01-04', '2024-02-13', '2024-03-12'])
})

# Compute delivery time in days
df_orders['delivery_days'] = (
    df_orders['delivery_date'] - df_orders['order_date']
).dt.days
print(df_orders)

インデックスの.dtプロパティの使用

datetimeが列ではなくDataFrameのインデックス(DatetimeIndex)になっている場合は、.dtを使わずにインデックスから同じプロパティへ直接アクセスします。たとえば、df.index.year、df.index.month、df.index.day_of_weekなどです。これらは、df['month'] = df.index.monthのようにして新しい列へ直接追加できます。

df_indexed = df.set_index('event_date')

# Access components directly on the DatetimeIndex
print(df_indexed.index.month[:3])  # [1, 1, 1]
print(df_indexed.index.day_of_week[:3])  # [0, 1, 2]

# Add as new columns
df_indexed['month']   = df_indexed.index.month
df_indexed['weekday'] = df_indexed.index.day_of_week
print(df_indexed.head())

時間特徴量エンジニアリングの完全なパイプライン

ここでは、datetime列を持つDataFrameを受け取り、最も役立つ時間特徴量を追加したDataFrameを返す、時間特徴量エンジニアリング関数の完全な例を示します。このパターンは、タイムスタンプ付きイベントデータを扱う機械学習または分析パイプラインの開始時に、そのまま適用できます。

def add_temporal_features(df, date_col):
    dt = df[date_col].dt
    df['year']       = dt.year
    df['month']      = dt.month
    df['day']        = dt.day
    df['day_of_week'] = dt.day_of_week
    df['quarter']    = dt.quarter
    df['is_weekend'] = dt.day_of_week >= 5
    df['month_sin']  = (2 * 3.14159 * dt.month / 12).__round__(4)
    df['month_cos']  = (2 * 3.14159 * dt.month / 12).__round__(4)
    return df

result = add_temporal_features(df.copy(), 'event_date')
print(result.columns.tolist())

理解度チェック

datetime列から時間特徴量を抽出する方法について、理解度を確認しましょう。

レッスンのまとめ

このレッスンでは、.dtアクセサーを使うと、すべてのdatetimeプロパティにベクトル化された形でアクセスできることを学びました。よく抽出される特徴量には、年、月、日、曜日、時、四半期があります。また、サイン・コサインによる周期性エンコーディングを使うと、時刻や月が持つ円環的な性質を扱えます。さらに、timedeltaの算術演算によって、日数や秒数で継続時間を計算できます。次は、出版品質のグラフを作成するためのMatplotlibのFigureとAxesの構造を学びます。

無料で開始

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

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

コース
30
レッスン
120

よくある質問

「時間特徴量の抽出」レッスンは無料ですか?

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

「時間特徴量の抽出」で何を学びますか?

.dtアクセサーを使って日時列からyear、month、day、day_of_week、hourを取り出し、特徴量を作成します。 ブラウザで直接実行するハンズオンコードで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. DatetimeIndexと期間範囲
  2. 時系列データのリサンプリング
  3. シフトとラグ特徴量
  4. 時間特徴量の抽出
← Pandas & NumPy Academyに戻る