Pandas resample使用问题:epoch参数与频率设置异常
如何让Pandas resample的origin='epoch'参数强制生效?
我想要生成一个索引为固定日期集合的时间序列,原本以为用带freq和origin='epoch'参数的resample方法就能实现,但实际使用下来发现参数好像没生效。
以下是第一个示例,设置origin="epoch"后,输出的索引日期如下:
import pandas as pd dates = pd.date_range('2022-01-01', '2022-02-01', freq="1D") freq = '2W-MON' vals = range(len(dates)) print( pd.Series(vals,index = dates) .resample(freq, origin="epoch", convention='end') .sum() .to_markdown() )
输出:
| 0 | |
|---|---|
| 2022-01-03 00:00:00 | 3 |
| 2022-01-17 00:00:00 | 133 |
| 2022-01-31 00:00:00 | 329 |
| 2022-02-14 00:00:00 | 31 |
当我把序列的起始日期改成2022-01-04后,得到的索引日期完全不同:
dates = pd.date_range('2022-01-04', '2022-02-01', freq="1D") freq = '2W-MON' vals = range(len(dates)) print( pd.Series(vals,index = dates) .resample(freq, origin="epoch", convention='end') .sum() .to_markdown() )
输出:
| 0 | |
|---|---|
| 2022-01-10 00:00:00 | 21 |
| 2022-01-24 00:00:00 | 189 |
| 2022-02-07 00:00:00 | 196 |
我期望设置freq='2W-MON'和origin='epoch'时,两次示例的结果应该有相同的索引日期(比如都是2022-01-10或者2022-01-03)。有没有优雅的方法能强制Pandas让origin='epoch'参数真正生效?
解决方案
问题出在Pandas对origin='epoch'的处理逻辑上——当使用相对频率(比如2W-MON这种基于锚点的频率)时,origin参数的优先级会被频率自身的锚点规则覆盖,它只会调整周期的起始偏移,而不会改变频率的锚点日期。
要强制生成基于epoch起始的固定周期索引,你可以手动计算出符合2W-MON规则且基于epoch的锚点日期,然后将其作为origin的具体日期传入,而不是用'epoch'字符串:
import pandas as pd # 计算epoch对应的周一(1970-01-01是周四,往前推3天到最近的周一:1969-12-29) epoch_anchor = pd.Timestamp('1969-12-29') # 通用函数:基于epoch锚点的resample def resample_epoch_aligned(series, freq): return series.resample(freq, origin=epoch_anchor, convention='end').sum() # 测试第一个示例 dates1 = pd.date_range('2022-01-01', '2022-02-01', freq="1D") vals1 = range(len(dates1)) s1 = pd.Series(vals1, index=dates1) print(resample_epoch_aligned(s1, '2W-MON').to_markdown()) # 测试第二个示例 dates2 = pd.date_range('2022-01-04', '2022-02-01', freq="1D") vals2 = range(len(dates2)) s2 = pd.Series(vals2, index=dates2) print(resample_epoch_aligned(s2, '2W-MON').to_markdown())
这样两次输出的索引会完全一致,都是基于1969-12-29(epoch最近的周一)开始的每两周周一的周期。
原理说明
2W-MON的本质是“每两周,以周一为周期结束/起始”,Pandas默认会根据数据的时间范围自动匹配最近的周一锚点,这就是为什么两次结果索引不同。- 手动指定
origin为epoch对应的周一后,所有周期都会以这个固定锚点为基准计算,不管数据的起始日期是什么,最终的索引集合都会保持一致。
内容的提问来源于stack exchange,提问作者Grzegorz Rut
相关产品推荐
相关产品推荐

