我正在努力找到一种适当的方法来解决使用熊猫进行重采样的问题,而不是使用可能容易出错的丑陋骇客。
假设我有一个这样的系列:
dates = pd.date_range('2018-01-03', '2018-09-13')
s = pd.Series(range(len(dates)), index=dates)
现在,我想将该系列重新采样为几个月,但要从索引的第一个日期开始,而不要从该月的第一天开始。例如,如果我只是重新采样为“ MS”,那么我得到的第一个日期是2018年1月1日,而不是2018年1月3日;当然,这是“月开始”,所以这是我应该期望的,但是如何在不从月初而是从同一月日开始抽取样本的情况下,每月进行一次重新抽样,从而得出的索引为例如[“ 2018-01-03”,“ 2018-02-03”等?
换句话说,如何使用“从索引中的第一个日期时间开始的月份”之类的东西重新采样?
到目前为止,我发现的唯一方法是在序列中创建一些前导日期,然后进行负移位,然后使用loffset参数(因为shift和loffset都不尊重数据与数据的对齐方式)索引),但这是我要避免的非常难看的骇客。
谢谢!
[解决方案]
我通过以下简单的步骤解决了这个问题,并适应了解决此问题的多种尝试(包括下面的第一个答复,还包括其他网站和SO提出的问题):
dates = pd.date_range('2018-01-03', '2018-09-13')
s = pd.Series(range(len(dates)), index=dates)
delta = dates.min() - (dates.min() - offsets.MonthBegin(1))
new_dates = dates - delta
s2 = s.copy()
s2.index = new_dates
resampled = s2.resample('MS', loffset=delta)
r_max = resampled.max()
r_min = resampled.min()
r_mean = resampled.mean()
r_sum = resampled.sum()
print('s\n', s)
print('r_max\n', r_max)
print('r_min\n', r_min)
print('r_mean\n', r_mean)
print('r_sum\n', r_sum)
感谢您的帮助!
答案 0 :(得分:1)
获取每月系列
dates = pd.date_range(s.index.min(), s.index.max(), freq='M')
在第一个日期之前返回MonthEnd并添加天数
dates = dates + pd.offsets.MonthEnd(-1) + pd.offsets.Day(s.index[0].day)
使用reindex
s.reindex(dates)
2018-01-03 0
2018-02-03 31
2018-03-03 59
2018-04-03 90
2018-05-03 120
2018-06-03 151
2018-07-03 181
2018-08-03 212
dtype: int64
答案 1 :(得分:0)
以您的回应为基础,减少您可以做的计算:
dates = pd.date_range('2018-01-03', '2018-09-13')
s = pd.Series(range(len(dates)), index=dates)
resampled = s.resample('MS', loffset=pd.Timedelta(days=s.index[0].day) - 1)
请注意,我不会复制到S2并分配完整的月份索引,因为重新采样已将初始日期设置为该月的1号。
感谢您的问题和答案,这很有用