为何pandas date_range会在月末起始时向上取整到下月?
Pandas date_range 起始为月末时按MS频率生成日期跳至下月的原因与解决办法
问题重现
当使用pandas.date_range,将月末日期设为起始点,同时指定freq="MS"(月初频率)和周期数时,生成的日期序列会从下月月初开始,而非预期的当月月初:
import pandas as pd start_date = pd.Timestamp(2023, 5, 31) date_range = pd.date_range(start=start_date, freq="MS", periods=6)
实际输出:
DatetimeIndex(['2023-06-01', '2023-07-01', '2023-08-01', '2023-09-01', '2023-10-01', '2023-11-01'], dtype='datetime64[ns]', freq='MS')
预期输出:
DatetimeIndex(['2023-05-01', '2023-06-01', '2023-07-01', '2023-08-01', '2023-09-01', '2023-10-01'], dtype='datetime64[ns]', freq='MS')
原因解析
这并非bug,是pandas对**锚定频率(Anchored Frequencies)**的标准处理逻辑:
MS属于锚定频率,锚点为每个月的第一天。- 当传入的起始日期不是该频率的锚点(比如5月31日不是月初)时,pandas会自动找到起始日期之后的第一个锚点日期作为序列的起始,再按指定频率生成后续周期。
- 5月31日之后的第一个
MS锚点是6月1日,因此序列从这里开始生成6个周期,最终到11月1日。
注:inclusive参数不影响此逻辑,它仅控制是否包含序列的首尾边界,而原起始日期本身不在MS频率的有效日期序列中,因此无法被包含。
解决办法
若要生成从当月月初开始的序列,可通过以下两种方式调整起始日期:
- 直接指定当月月初为起始日期:
import pandas as pd start_date = pd.Timestamp(2023, 5, 1) date_range = pd.date_range(start=start_date, freq="MS", periods=6)
- 将月末日期回滚至当月月初:
使用pd.offsets.MonthBegin().rollback()方法,将非月初日期调整为当月的第一个锚点:
import pandas as pd start_date = pd.Timestamp(2023, 5, 31) adjusted_start = pd.offsets.MonthBegin().rollback(start_date) date_range = pd.date_range(start=adjusted_start, freq="MS", periods=6)
内容的提问来源于stack exchange,提问作者franktcao
相关产品推荐
相关产品推荐

