pd.date_range() 默认 end 为闭区间,但仅当 freq 能整除时间跨度时才包含;否则停在 end 前最近对齐点,强制包含需设 inclusive='both'(pandas ≥ 1.4.0)。

pd.date_range() 为什么生成的日期不包含 end?
默认情况下 pd.date_range() 的 end 是闭区间(包含),但前提是 freq 能整除时间跨度。比如从 '2023-01-01' 到 '2023-01-05' 用 freq='D',会生成 5 天;但若用 freq='2D','2023-01-05' 不在步长对齐点上,就会被截断——实际停在 '2023-01-05' 之前最近的合法点(即 '2023-01-05' 不出现)。
- 想强制包含
end,加参数inclusive='both'(Pandas ≥ 1.4.0) - 旧版本(periods +
freq推算长度,或手动追加end -
inclusive='neither'或'left'会影响边界,别默认以为“写了 end 就一定有”
freq 参数写错导致结果完全不对
freq 不是字符串拼写自由发挥的地方。写成 'day'、'daily' 或漏掉引号都会报错或静默降级为默认频率。
- 必须用 Pandas 官方缩写:如
'D'(日)、'MS'(月首)、'B'(工作日)、'H'(小时) -
'M'是月末,'MS'才是月初——差一个字母,起点天差地别 - 带偏移量要写全,比如
'2D'、'W-FRI'(每周五),不能写'W'就默认周五 - 中文文档里常见的“日”“月”等字面量,在代码里一律无效
时区敏感场景下 date_range 行为突变
一旦给 start 或 end 加了时区(如 '2023-01-01T00:00:00+08:00'),整个序列自动带时区,且 freq 按本地时钟滚动——夏令时切换那天可能多出或少掉一小时。
- 跨时区对齐建议统一转成 UTC 再生成,最后再
.dt.tz_convert() - 避免混用有时区和无时区的时间点,否则报
TypeError: Cannot mix tz-aware and tz-naive timestamps - 用
tz_localize()比直接字符串加 offset 更可靠,尤其处理模糊时间(如冬夏令时交界)
性能陷阱:大范围 + 高频 freq 容易爆内存
pd.date_range('1970-01-01', '2100-01-01', freq='S') 看似合理,实际生成超 40 亿个 Timestamp 对象,轻松吃光几 GB 内存。
- 日频(
'D')覆盖百年约 4.8 万项,安全;秒频('S')覆盖一天就 86400 项 - 真需要高频时间轴,优先考虑
pd.period_range()(更轻量)或分块生成 - 生成后立刻用
.astype('datetime64[ns]')可省约 30% 内存,但无法改变对象数量级
最常被忽略的一点:date_range 返回的是不可变的 DatetimeIndex,没法原地增删。想动态扩展?得重新生成或转成 list + pd.to_datetime() ——但那就不是“时间轴”而是普通数组了。










