Pandas & NumPy Academy · 课时

DatetimeIndex 与周期范围

使用 pd.date_range 创建 DatetimeIndex,解析字符串日期,并将时间列设为索引以便按时间访问。

第 1 / 4 课13 个步骤

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

为什么 Pandas 有专门的时间工具

时间序列数据的处理不只是将日期存储为字符串。您还需要按时间排序、选择日期范围、重采样到不同频率,以及提取月份和星期几等组成部分。Pandas 通过 DatetimeIndex 解决了这些问题——它是一种由 datetime64 值组成的索引,可启用普通整数索引或字符串索引不具备的专用时间操作。

使用 pd.date_range() 创建 DatetimeIndex

pd.date_range(start, end, freq) 会生成一系列间隔均匀的日期。freq 参数使用偏移别名指定间隔:'D' 表示天,'h' 表示小时,'ME' 表示月末,'W' 表示周,'YE' 表示年末。您可以传入 end 或 periods(时间戳数量)中的一个,但不能同时传入两者。

import pandas as pd

# Daily dates for January 2024
dates = pd.date_range(start='2024-01-01', end='2024-01-07', freq='D')
print(dates)
# DatetimeIndex(['2024-01-01', '2024-01-02', '2024-01-03',
#                '2024-01-04', '2024-01-05', '2024-01-06', '2024-01-07'],
#               dtype='datetime64[ns]', freq='D')

# 12 month-end dates
months = pd.date_range(start='2024-01-31', periods=12, freq='ME')
print(months[:3])

在 DataFrame 上设置 DatetimeIndex

要启用基于时间的操作,请先使用 pd.to_datetime() 将日期列转换为 datetime64,然后使用 set_index() 将其设为 DataFrame 的索引。索引成为 DatetimeIndex 后,您就可以使用部分字符串索引(df['2024-01'])、日期范围切片以及所有面向时间的函数。

df = pd.DataFrame({
    'date':  ['2024-01-01', '2024-01-02', '2024-01-03'],
    'value': [10, 15, 12]
})

df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date')
print(df)
#             value
# date
# 2024-01-01     10
# 2024-01-02     15
# 2024-01-03     12
print(type(df.index))  # DatetimeIndex

部分字符串索引

DatetimeIndex 最方便的功能之一是部分字符串索引。您可以将不完整的日期字符串传给 .loc[],按年、月或日期选择行。例如,df.loc['2024-01'] 会返回 2024 年 1 月的所有行,而 df.loc['2024'] 会返回 2024 年的所有行。您无需显式比较列值。

# Create a larger date-indexed Series
s = pd.Series(
    range(365),
    index=pd.date_range('2024-01-01', periods=365, freq='D')
)

# Select all of January 2024
print(s.loc['2024-01'].shape)  # (31,)

# Select a specific date range
print(s.loc['2024-03-01':'2024-03-07'])

使用 pd.to_datetime() 进行解析

pd.to_datetime() 会将字符串、整数(Unix 时间戳)或格式混杂的日期列转换为 datetime64。如果日期采用非标准格式,请传入 format 指定确切的模式,例如 '%d/%m/%Y'。使用 errors='coerce' 可将无法解析的值转换为 NaT(非时间),而不是引发错误。

# Parse standard ISO format
print(pd.to_datetime('2024-06-15'))

# Parse non-standard format
print(pd.to_datetime('15/06/2024', format='%d/%m/%Y'))

# Handle mixed/bad data gracefully
mixed = pd.to_datetime(['2024-01-01', 'bad_date', '2024-06-15'],
                       errors='coerce')
print(mixed)  # NaT for 'bad_date'

用于提取日期时间组成部分的 .dt 访问器

当 DataFrame 的某一列(而不是索引)包含 datetime64 值时,.dt 访问器会以向量化方式提供该列的所有日期时间属性和函数。您可以使用它提取 .dt.year、.dt.month、.dt.day、.dt.day_of_week、.dt.hour 等信息,而无需使用循环。如果日期时间值位于索引中,则直接使用 df.index.year。

df_col = pd.DataFrame({'date': pd.date_range('2024-01-01', periods=5, freq='D'),
                       'value': [10, 15, 12, 18, 14]})

df_col['year']  = df_col['date'].dt.year
df_col['month'] = df_col['date'].dt.month
df_col['dow']   = df_col['date'].dt.day_of_week  # 0=Monday
df_col['week']  = df_col['date'].dt.isocalendar().week
print(df_col.head())

使用 pd.period_range() 创建周期范围

PeriodIndex 表示时间的区间,而不是具体的时间戳。pd.period_range(start, periods, freq) 可以创建月度、季度或年度周期。像 Period('2024-01', 'M') 这样的周期表示 2024 年 1 月的整个月份,而不仅仅是月初日期。在按季度或月份进行思考的财务报告中,PeriodIndex 非常有用。

# Monthly periods
periods = pd.period_range('2024-01', periods=6, freq='M')
print(periods)
# PeriodIndex(['2024-01', '2024-02', '2024-03',
#              '2024-04', '2024-05', '2024-06'],
#             dtype='period[M]')

# Quarterly periods
quarters = pd.period_range('2024Q1', periods=4, freq='Q')
print(quarters)  # [2024Q1, 2024Q2, 2024Q3, 2024Q4]

在时间戳和周期之间转换

您可以使用 to_period(freq) 将 DatetimeIndex 转换为 PeriodIndex,再使用 to_timestamp() 转换回来。当您希望按月份或季度而不是具体日期标记行时,转换为周期非常有用;对于基于日历的分析,这样可以让分组和聚合更加直观。

daily_idx = pd.date_range('2024-01-15', periods=5, freq='D')
print('DatetimeIndex:', daily_idx[:3])

# Convert to monthly periods
monthly_idx = daily_idx.to_period('M')
print('PeriodIndex:', monthly_idx[:3])
# PeriodIndex(['2024-01', '2024-01', ...], dtype='period[M]')

# Convert back to timestamps (start of period)
print(monthly_idx.to_timestamp()[:3])

处理时区

现实中的时间序列通常包含时区信息。Pandas 通过 tz_localize()(为无时区的时间戳附加时区)和 tz_convert()(在不同时区之间转换)支持带时区的 DatetimeIndex。请始终在内部使用 UTC 进行处理,仅在显示时转换为本地时间,以避免夏令时歧义导致的错误。

naive = pd.date_range('2024-01-01', periods=3, freq='D')
print('Naive:', naive.tz)

# Attach timezone (localize)
utc = naive.tz_localize('UTC')
print('UTC:', utc)

# Convert to New York time
ny = utc.tz_convert('America/New_York')
print('NY:', ny[:2])

检查和排序 DatetimeIndex

重采样和切片等时间序列操作要求 DatetimeIndex 已排序(单调递增)。请使用 df.index.is_monotonic_increasing 进行检查,并在需要时使用 df.sort_index() 排序。未排序的 DatetimeIndex 可能会在重采样和窗口函数中导致不易察觉的错误或意外结果。

import numpy as np

df_unsorted = pd.DataFrame(
    {'value': [10, 15, 12]},
    index=pd.to_datetime(['2024-01-03', '2024-01-01', '2024-01-02'])
)
print('Sorted:', df_unsorted.index.is_monotonic_increasing)  # False

df_sorted = df_unsorted.sort_index()
print('After sort:', df_sorted.index.is_monotonic_increasing)  # True
print(df_sorted)

实用模式:构建时间序列 DataFrame

下面介绍一种从原始数据构建按时间索引的 DataFrame 的完整模式:解析日期、设置索引、排序,并验证索引频率。这种设置是后续所有时间序列分析的基础——重采样、滚动平均值和滞后特征都依赖于整洁且已排序的 DatetimeIndex。

import numpy as np

# Simulate loading raw data
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=30, freq='D')
df_ts = pd.DataFrame({'sales': np.random.randint(100, 500, 30)}, index=dates)

df_ts.index.name = 'date'
print('Shape:', df_ts.shape)
print('Freq:', df_ts.index.freq)
print('Sorted:', df_ts.index.is_monotonic_increasing)
print(df_ts.head())

快速检查

测试您对本课中 DatetimeIndex 和周期范围的理解。

课程回顾

在本课中,您学习了:如何使用 pd.date_range() 创建 DatetimeIndex,以及如何使用 pd.to_datetime() 解析日期;如何使用部分字符串索引直观地选择日期;Timestamp 和 Period 类型之间的区别;以及如何处理时区。接下来,我们将探索重采样,以改变时间序列的频率。

免费开始

用 AI 导师学习 Python — 免费

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

课程
30
课程
120

常见问题解答

「DatetimeIndex 与周期范围」课时是免费的吗?

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

「DatetimeIndex 与周期范围」这节课中我会学到什么?

使用 pd.date_range 创建 DatetimeIndex,解析字符串日期,并将时间列设为索引以便按时间访问。 你通过在浏览器中直接运行的动手代码来练习 Pandas & NumPy Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Pandas & NumPy Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Pandas & NumPy Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「DatetimeIndex 与周期范围」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Pandas & NumPy Academy 课中编写并运行代码吗?

能。每节 Pandas & NumPy Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. DatetimeIndex 与周期范围
  2. 重采样时间序列
  3. 移动与滞后特征
  4. 提取时间特征
← 返回 Pandas & NumPy Academy