Pandas pd.date_range() 函数
pd.date_range() 是 Pandas 库中用于生成日期范围的函数。它可以创建一个包含连续日期的 DatetimeIndex,常用于时间序列数据的创建、索引和对齐。
在时间序列分析中,经常需要生成固定频率的日期序列,例如每日、每月或每年的数据。pd.date_range() 提供了灵活的参数来满足各种频率需求。
单词释义: date_range 意为"日期范围",即生成一系列连续日期的集合。
基本语法与参数
pd.date_range() 是 Pandas 库的顶级函数,用于生成指定频率的日期时间索引。
语法格式
pd.date_range(start=None, end=None, periods=None, freq=None, tz=None, normalize=False, name=None, closed=None)
参数说明
| 参数 | 类型 | 是否必填 | 说明 | 默认值 |
|---|---|---|---|---|
| start | 字符串或 datetime | 可选 | 起始日期。 | None |
| end | 字符串或 datetime | 可选 | 结束日期。 | None |
| periods | 整数 | 可选 | 生成日期的数量。与 start/end 三选二。 | None |
| freq | 字符串或 DateOffset | 可选 | 频率:'D'(天)、'H'(小时)、'M'(月末)、'MS'(月初)、'Y'(年末)、'W'(周)等。 | 'D' |
| tz | 字符串 | 可选 | 时区名称,如 'UTC'、'Asia/Shanghai'。 | None |
| normalize | 布尔值 | 可选 | True 则将时间归一化到午夜。 | False |
| name | 字符串 | 可选 | 生成的 DatetimeIndex 的名称。 | None |
| closed | 字符串 | 可选 | 区间开闭:'left'、'right'、None(默认两者都闭)。 | None |
返回值说明
- 返回值: 返回一个 DatetimeIndex 对象,包含连续的日期时间。
- 效果: 根据指定的起始日期、结束日期和频率生成日期序列。
实例
让我们通过一系列从简单到复杂的例子,彻底掌握 pd.date_range() 的用法。
示例 1:基础用法 - 生成日期范围
实例
import pandas as pd
# 1. 使用 start 和 end 参数生成日期范围(默认频率为天)
print("=== 从 2023-01-01 到 2023-01-10 ===")
dates = pd.date_range(start='2023-01-01', end='2023-01-10')
print(dates)
print(f"类型: {type(dates)}")
print(f"数据类型: {dates.dtype}")
# 2. 使用 periods 参数指定生成数量
print("n=== 生成 7 天的日期 ===")
week_dates = pd.date_range(start='2023-01-01', periods=7)
print(week_dates)
# 3. 使用 freq 参数指定频率
print("n=== 每周一个日期 (freq='W') ===")
weekly_dates = pd.date_range(start='2023-01-01', periods=5, freq='W')
print(weekly_dates)
# 4. 每月初的日期 (freq='MS' = Month Start)
print("n=== 每月初 (freq='MS') ===")
monthly_dates = pd.date_range(start='2023-01-01', periods=6, freq='MS')
print(monthly_dates)
# 5. 每年末的日期 (freq='YE' = Year End)
print("n=== 每年末 (freq='YE') ===")
yearly_dates = pd.date_range(start='2023-01-01', periods=3, freq='YE')
print(yearly_dates)
# 1. 使用 start 和 end 参数生成日期范围(默认频率为天)
print("=== 从 2023-01-01 到 2023-01-10 ===")
dates = pd.date_range(start='2023-01-01', end='2023-01-10')
print(dates)
print(f"类型: {type(dates)}")
print(f"数据类型: {dates.dtype}")
# 2. 使用 periods 参数指定生成数量
print("n=== 生成 7 天的日期 ===")
week_dates = pd.date_range(start='2023-01-01', periods=7)
print(week_dates)
# 3. 使用 freq 参数指定频率
print("n=== 每周一个日期 (freq='W') ===")
weekly_dates = pd.date_range(start='2023-01-01', periods=5, freq='W')
print(weekly_dates)
# 4. 每月初的日期 (freq='MS' = Month Start)
print("n=== 每月初 (freq='MS') ===")
monthly_dates = pd.date_range(start='2023-01-01', periods=6, freq='MS')
print(monthly_dates)
# 5. 每年末的日期 (freq='YE' = Year End)
print("n=== 每年末 (freq='YE') ===")
yearly_dates = pd.date_range(start='2023-01-01', periods=3, freq='YE')
print(yearly_dates)
运行结果:
=== 从 2023-01-01 到 2023-01-10 ===
DatetimeIndex(['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04', '2023-01-05',
'2023-01-06', '2023-01-07', '2023-01-08', '2023-01-09', '2023-01-10'],
dtype='datetime64[ns]', freq='D')
类型: <class 'pandas.core.indexes.datetimes.DatetimeIndex'>
数据类型: datetime64[ns]
=== 生成 7 天的日期 ===
DatetimeIndex(['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04', '2023-01-05',
'2023-01-06', '2023-01-07'], dtype='datetime64[ns]', freq='D')
=== 每周一个日期 (freq='W') ===
DatetimeIndex(['2023-01-01', '2023-01-08', '2023-01-15', '2023-01-22', '2023-01-29'], dtype='datetime64[ns]', freq='W-SUN')
=== 每月初 (freq='MS') ===
DatetimeIndex(['2023-01-01', '2023-02-01', '2023-03-01', '2023-04-01', '2023-05-01',
'2023-06-01'], dtype='datetime64[ns]', freq='MS')
=== 每年末 (freq='YE') ===
DatetimeIndex(['2023-12-31', '2024-12-31', '2025-12-31'], dtype='datetime64[ns]', freq='YE-DEC')
代码解析:
pd.date_range()默认生成每日频率的日期序列。freq参数支持多种频率缩写:'D'(天)、'W'(周)、'M'(月末)、'MS'(月初)、'Y'(年末)、'H'(小时)等。- 返回的是 DatetimeIndex 对象,可以直接用于 Series 或 DataFrame 的索引。
示例 2:生成时间序列数据
创建带有日期索引的 DataFrame,用于时间序列分析。
实例
import pandas as pd
import numpy as np
# 1. 创建一个带日期索引的 DataFrame
print("=== 创建一个简单的时间序列 ===")
# 生成30天的日期
date_index = pd.date_range(start='2023-01-01', periods=30, freq='D')
# 创建 DataFrame
df = pd.DataFrame({
'date': date_index,
'value': np.random.randint(10, 100, size=30), # 随机值
'category': ['A', 'B'] * 15 # 交替分类
})
print(df.head(10))
# 2. 设置日期为索引
print("n=== 设置日期为索引 ===")
df_indexed = df.set_index('date')
print(df_indexed.head())
# 3. 生成每小时的数据(用于日志分析)
print("n=== 每小时的时间序列 ===")
hourly_index = pd.date_range(start='2023-01-01 08:00', periods=24, freq='H')
hourly_data = pd.DataFrame({
'timestamp': hourly_index,
'visitors': np.random.randint(0, 100, size=24)
})
print(hourly_data)
import numpy as np
# 1. 创建一个带日期索引的 DataFrame
print("=== 创建一个简单的时间序列 ===")
# 生成30天的日期
date_index = pd.date_range(start='2023-01-01', periods=30, freq='D')
# 创建 DataFrame
df = pd.DataFrame({
'date': date_index,
'value': np.random.randint(10, 100, size=30), # 随机值
'category': ['A', 'B'] * 15 # 交替分类
})
print(df.head(10))
# 2. 设置日期为索引
print("n=== 设置日期为索引 ===")
df_indexed = df.set_index('date')
print(df_indexed.head())
# 3. 生成每小时的数据(用于日志分析)
print("n=== 每小时的时间序列 ===")
hourly_index = pd.date_range(start='2023-01-01 08:00', periods=24, freq='H')
hourly_data = pd.DataFrame({
'timestamp': hourly_index,
'visitors': np.random.randint(0, 100, size=24)
})
print(hourly_data)
运行结果:
=== 创建一个简单的时间序列 ===
date value category
0 2023-01-01 67 A
1 2023-01-02 23 B
2 2023-01-03 45 A
3 2023-01-04 89 B
4 2023-01-05 12 A
5 2023-01-06 34 B
6 2023-01-07 56 A
7 2023-01-08 78 B
8 2023-01-09 91 A
9 2023-01-10 55 B
=== 设置日期为索引 ===
value category
date
2023-01-01 67 A
2023-01-02 23 B
2023-01-03 45 A
2023-01-04 89 B
2023-01-05 12 A
2023-01-06 34 B
=== 每小时的时间序列 ===
timestamp visitors
0 2023-01-01 08:00:00 25
1 2023-01-01 09:00:00 41
2 2023-01-01 10:00:00 77
3 2023-01-01 11:00:00 12
4 2023-01-01 12:00:00 58
5 2023-01-01 13:00:00 33
6 2023-01-01 14:00:00 45
7 2023-01-01 15:00:00 67
8 2023-01-01 16:00:00 29
9 2023-01-01 17:00:00 51
10 2023-01-01 18:00:00 44
11 2023-01-01 19:00:00 36
12 2023-01-01 20:00:00 28
13 2023-01-01 21:00:00 62
14 2023-01-01 22:00:00 19
15 2023-01-01 23:00:00 73
16 2023-01-02 00:00:00 41
17 2023-01-02 01:00:00 55
18 2023-01-02 02:00:00 38
19 2023-01-02 03:00:00 27
20 2023-01-02 04:00:00 49
21 2023-01-02 05:00:00 63
22 2023-01-02 06:00:00 34
23 2023-01-02 07:00:00 56
代码解析:
- DatetimeIndex 可以直接作为 DataFrame 的索引使用。
- 日期索引的 DataFrame 支持丰富的时序操作,如重采样、滚动计算等。
freq='H'可以生成小时级别的数据,适用于日志分析等场景。
示例 3:时区和 closed 参数
实例
import pandas as pd
# 1. 使用 tz 参数指定时区
print("=== 带时区的日期范围 ===")
dates_tz = pd.date_range(start='2023-01-01', periods=3, freq='D', tz='Asia/Shanghai')
print(dates_tz)
print(f"时区: {dates_tz.tz}")
# 2. 使用 UTC 时区
print("n=== UTC 时区 ===")
dates_utc = pd.date_range(start='2023-01-01', periods=3, freq='D', tz='UTC')
print(dates_utc)
# 3. 使用 closed 参数控制区间开闭
print("n=== closed 参数对比 ===")
print("closed=None (默认, 两端都闭):", pd.date_range('2023-01-01', '2023-01-03', freq='D', closed=None))
print("closed='left':", pd.date_range('2023-01-01', '2023-01-03', freq='D', closed='left'))
print("closed='right':", pd.date_range('2023-01-01', '2023-01-03', freq='D', closed='right'))
# 4. 使用 normalize 参数归一化时间
print("n=== normalize 参数 ===")
dates_with_time = pd.date_range(start='2023-01-01 14:30:00', periods=3, freq='H')
print("归一化前:", dates_with_time)
dates_normalized = pd.date_range(start='2023-01-01 14:30:00', periods=3, freq='H', normalize=True)
print("归一化后:", dates_normalized)
# 1. 使用 tz 参数指定时区
print("=== 带时区的日期范围 ===")
dates_tz = pd.date_range(start='2023-01-01', periods=3, freq='D', tz='Asia/Shanghai')
print(dates_tz)
print(f"时区: {dates_tz.tz}")
# 2. 使用 UTC 时区
print("n=== UTC 时区 ===")
dates_utc = pd.date_range(start='2023-01-01', periods=3, freq='D', tz='UTC')
print(dates_utc)
# 3. 使用 closed 参数控制区间开闭
print("n=== closed 参数对比 ===")
print("closed=None (默认, 两端都闭):", pd.date_range('2023-01-01', '2023-01-03', freq='D', closed=None))
print("closed='left':", pd.date_range('2023-01-01', '2023-01-03', freq='D', closed='left'))
print("closed='right':", pd.date_range('2023-01-01', '2023-01-03', freq='D', closed='right'))
# 4. 使用 normalize 参数归一化时间
print("n=== normalize 参数 ===")
dates_with_time = pd.date_range(start='2023-01-01 14:30:00', periods=3, freq='H')
print("归一化前:", dates_with_time)
dates_normalized = pd.date_range(start='2023-01-01 14:30:00', periods=3, freq='H', normalize=True)
print("归一化后:", dates_normalized)
运行结果:
=== 带时区的日期范围 === DatetimeIndex(['2023-01-01', '2023-01-02', '2023-01-03'], dtype='datetime64[ns, Asia/Shanghai]') 时区: Asia/Shanghai === UTC 时区 === DatetimeIndex(['2023-01-01', '2023-01-02', '2023-01-03'], dtype='datetime64[ns, UTC]') === closed 参数对比 === closed=None (默认, 两端都闭): DatetimeIndex(['2023-01-01', '2023-01-02', '2023-01-03']) closed='left': DatetimeIndex(['2023-01-01', '2023-01-02']) closed='right': DatetimeIndex(['2023-01-02', '2023-01-03']) === normalize 参数 === 归一化前: DatetimeIndex(['2023-01-01 14:30:00', '2023-01-01 15:30:00', '2023-01-01 16:30:00']) 归一化后: DatetimeIndex(['2023-01-01', '2023-01-02', '2023-01-03'])
代码解析:
tz参数可以指定时区,处理跨时区的数据时非常有用。closed参数可以控制日期区间的开闭,默认为两端都闭。normalize=True将时间归一化到午夜,方便按日期聚合数据。
注意事项
重要提示:
- 必须指定
start和end,或者指定start和periods,或者指定end和periods,不能同时只指定一个。- 频率缩写是大小写敏感的,如 'D' 表示天,'d' 会报错。
- 处理时区数据需要确保所有日期使用统一的时区,否则可能产生意外结果。
- 生成大量日期(如多年数据)时注意内存占用。

Pandas 常用函数