Pandas & NumPy Academy · 课时

提取时间特征

使用 .dt 访问器从日期时间列中提取 year、month、day、day_of_week 和 hour,用于特征工程。

第 4 / 4 课13 个步骤

提取时间特征 是 CoddyKit 上的免费 Pandas & NumPy Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Pandas & NumPy Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Pandas & NumPy Academy 课程共包含 4 节课。

为什么要提取时间特征

原始的 datetime64 列对大多数机器学习算法来说并不直观——算法无法理解 2024-12-25 是节假日,也无法理解 Friday 会带来更高的零售销售额。时间特征工程会从 datetime 列中提取有意义的组成部分——年、月、日、星期几、小时——将它们作为独立的数值型或分类型列,使模型和分析函数可以直接使用。

.dt 访问器

当 DataFrame 列的数据类型为 datetime64 时,.dt 访问器会以向量化方式提供所有 datetime 属性和方法。您无需逐行应用 Python 函数,只需写出 df['date'].dt.year,Pandas 就会通过一次快速操作计算每一行的年份。同一访问器也适用于 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)。这样会将环形结构嵌入两个数值列中,模型便能正确使用这些特征。

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 算术运算

将两个 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,并返回添加了最有用时间特征的数据。这种模式可以直接应用于任何处理带时间戳事件数据的机器学习或分析流程的开头。

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 属性;常见的提取特征包括年、月、日、day_of_week、小时和季度;使用正弦/余弦进行周期性编码可以处理小时和月份的环形特征;而 timedelta 算术运算可以帮助您计算以天或秒为单位的持续时间。接下来,我们将探索 Matplotlib 的图形和坐标轴架构,以创建适合发表的图表。

免费开始

用 AI 导师学习 Python — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
30
课程
120

常见问题解答

「提取时间特征」课时是免费的吗?

是的 — 「提取时间特征」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Pandas & NumPy Academy 课程的其余内容,请升级到 CoddyKit PRO。 Pandas & NumPy Academy 课程共包含 4 节课。

「提取时间特征」这节课中我会学到什么?

使用 .dt 访问器从日期时间列中提取 year、month、day、day_of_week 和 hour,用于特征工程。 你通过在浏览器中直接运行的动手代码来练习 Pandas & NumPy Academy,全天候 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