我从每月系列的时间戳开始,作为月底。我想通过填充前向值将它们上传到商业(周一至周五)每日频率。 我希望有两个条件成立:
虽然不优雅,但我得出结论,最安全的方法是:
daily_series = monthly_series.resample(rule='D').ffill().resample(rule='B',how='first')
现在,出乎意料的是:
dates = ['1953-02-28', '1953-03-31', '1953-04-30', '1953-05-31']
# '1953-02-28' was a Saturday
values = [1,2,3,4]
monthly_ts = pd.Series(values, index = dates)
monthly_ts
Out[74]:
1953-02-28 1
1953-03-31 2
1953-04-30 3
1953-05-31 4
dtype: int64
daily_ts = monthly_ts.resample(rule='D').ffill().resample(rule='B',how='first')
Out[77]:
1953-02-27 1 # Why do I have this observation?
1953-03-02 1
1953-03-03 1
1953-03-04 1
星期六的观察结果在星期五用于重新取样。 这发生在.resample(rule =' B')
之后您能否向我解释为什么会发生这种情况以及如何防止这种情况发生?
答案 0 :(得分:2)
这种行为方式是由于制作下采样时段而发生的。 间隔中的工作日数小于日历日。 这就是为什么星期五和星期一加入星期六和星期日,并作为一个单位表示。 星期六和星期日的值用于使用'how'和'closed'参数进行下采样。</ p>
dates = ['1953-02-28', '1953-03-31', '1953-04-30', '1953-05-31']
values = [1,2,3,4]
monthly_ts = pd.Series(values, index = pd.to_datetime(dates))
首次上传到日历日
calendar_daily_ts = monthly_ts.resample(rule='D').ffill()
让我们看看最后三个记录
In[8]: calendar_daily_ts[-3:]
Out[8]:
1953-05-29 3
1953-05-30 3
1953-05-31 4
Freq: D, dtype: int64
如果我们使用mean和closed ='left'下采样到工作日,那么最后一个值将是3.33333
In [15]: calendar_daily_ts.resample(rule='B', closed='left').mean()[-2:]
Out[15]:
1953-05-28 3.000000
1953-05-29 3.333333
Freq: B, dtype: float64
周五(1953-05-29)的价值计算为周五,周六和周日(3 + 3 + 4)/ 3的平均值
如果我们使用mean和closed ='right'下采样到工作日,则最后一个值将为3.5
In [16]: calendar_daily_ts.resample(rule='B', closed='right').mean()[-2:]
Out[16]:
1953-05-28 3.0
1953-05-29 3.5
Freq: B, dtype: float64
周五(1953-05-29)的价值计算为周六,周日和下周一(3 + 4 + 0)/ 2的平均值
没有周五价值。
所以你问题中的观察结果是因为在1953-02-28(星期六),下采样的时期包括1953-02-27,1953-02-28,1953-03-01和1953-03-02。 默认间隔是左边的 - (1953-02-27,1953-02-28,1953-03-01)。 你得到了第一个 - 它是1953-02-27
另一个有趣的例子
In [45]: calendar_daily_ts[:4]
Out[45]:
1953-02-27 1
1953-02-28 2
1953-03-01 3
1953-03-02 4
dtype: int64
In [47]: calendar_daily_ts.resample(rule='B', closed='left').first()[:4]
Out[47]:
1953-02-27 1
1953-03-02 4
1953-03-03 1
1953-03-04 1
Freq: B, dtype: int64
In [48]: calendar_daily_ts.resample(rule='B', closed='right').first()[:4]
Out[48]:
1953-02-26 1
1953-02-27 2
1953-03-02 1
1953-03-03 1
Freq: B, dtype: int64
看到差异! (1953-02-26,价值1)