Pandas DateOffset行为不一致:累加12个月为何结果不同?
为什么累加相同总月份数却得到不同的Timestamp结果?
这不是bug,而是pandas处理DateOffset时的预期行为——核心原因是每次应用月份偏移时,pandas会逐个调整日期,遇到目标月份没有对应日期的情况会自动回滚到当月最后一天,多次偏移后就会产生累积差异。
拆解两种计算的具体过程
我们来一步步看你的代码执行逻辑:
t1的计算路径(4次累加3个月)
- 初始日期:
2020-05-29 - 第一次加3个月:
2020-05-29 + 3个月 = 2020-08-29(8月有29日,无回滚) - 第二次加3个月:
2020-08-29 + 3个月 = 2020-11-29(11月有29日,无回滚) - 第三次加3个月:
2020-11-29 + 3个月本应到2021-02-29,但2021是平年,2月只有28天,所以pandas自动回滚到当月最后一天:2021-02-28 - 第四次加3个月:
2021-02-28 + 3个月 = 2021-05-28(从2月28日累加3个月,直接到5月28日)
t2的计算路径(2次累加6个月)
- 初始日期:
2020-05-29 - 第一次加6个月:
2020-05-29 + 6个月 = 2020-11-29(11月有29日,无回滚) - 第二次加6个月:
2020-11-29 + 6个月 = 2021-05-29(5月有29日,无回滚)
可见,t1在第三次偏移时触发了日期回滚,后续的偏移基于回滚后的日期计算,最终导致结果和t2不同。
如何得到预期的结果?
如果你需要精确累加12个月,最好直接一次性指定总月份数,避免多次偏移带来的累积影响:
import pandas as pd t_correct = pd.Timestamp('2020-05-29') + pd.DateOffset(months=12) # 结果:Timestamp('2021-05-29 00:00:00')
如果必须分多次操作,也可以借助dateutil的relativedelta(它的月份偏移逻辑更贴近“保持日期尽可能一致”的预期):
from dateutil.relativedelta import relativedelta t1_fixed = pd.Timestamp('2020-05-29') + 4 * relativedelta(months=3) # 结果:Timestamp('2021-05-29 00:00:00')
内容的提问来源于stack exchange,提问作者user1726633




