DatetimeIndex 与周期范围
使用 pd.date_range 创建 DatetimeIndex,解析字符串日期,并将时间列设为索引以便按时间访问。
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 反馈 — 无需本地设置。