Python 使用pandas在滚动窗口中重新采样

Python 使用pandas在滚动窗口中重新采样,python,pandas,resampling,Python,Pandas,Resampling,假设我有每日数据(不规则间隔),我想计算过去5个月内每个月的移动标准偏差(或任意的非线性函数)。例如,对于2012年5月,我将计算2012年1月至2012年5月(5个月)期间的STDEV。对于2012年6月,周期从2012年2月开始,以此类推。最终结果是具有月度值的时间序列 我无法应用滚动窗口,因为这将首先是每天,其次我需要指定值的数量(滚动窗口不按时间范围聚合,一些帖子解决了这一问题,但它们与我的问题无关,因为滚动仍然适用于新的一天) I无法应用重采样,因为这样样本将每5个月进行一次,例如,我

假设我有每日数据(不规则间隔),我想计算过去5个月内每个月的移动标准偏差(或任意的非线性函数)。例如,对于2012年5月,我将计算2012年1月至2012年5月(5个月)期间的STDEV。对于2012年6月,周期从2012年2月开始,以此类推。最终结果是具有月度值的时间序列

无法应用滚动窗口,因为这将首先是每天,其次我需要指定值的数量(滚动窗口不按时间范围聚合,一些帖子解决了这一问题,但它们与我的问题无关,因为滚动仍然适用于新的一天)

I无法应用重采样,因为这样样本将每5个月进行一次,例如,我将仅具有2012年5月、2012年10月、2013年3月的值。。。最后,由于函数是非线性的,我不能通过先做一个月的样本,然后在其上应用一个5周期的滚动窗口来重建它

因此,我需要一种应用于由时间间隔(而不是值的数量)定义的滚动窗口的重采样功能


我怎样才能在熊猫身上做到这一点?一种方法是组合几个(本例中为5个)重采样(5个月)时间序列,每个时间序列有一个月的偏移量,然后将所有这些序列对齐成一个。。。但我不知道如何实现这一点。

这里有一个尝试-不是超级干净,但它可能会工作

虚拟数据:

df = pd.DataFrame(data={'a': 1.}, 
                  index=pd.date_range(start='2001-1-1', periods=1000))

首先定义一个函数来减少日期
n
月数。这需要清理,但适用于n我在处理时间差序列时遇到了类似的问题,我想取一个移动平均值,然后重新采样。这里是一个例子,我有100秒的数据。我采用10秒窗口的滚动平均值,然后每5秒重新采样一次,在每个重新采样箱中取第一个条目。结果应为前10秒的平均值,增量为5秒。您可以使用月格式而不是秒格式执行类似操作:

df = pd.DataFrame(range(0,100), index=pd.TimedeltaIndex(range(0,100),'s'))
df.rolling('10s').mean().resample('5s').first()
结果:

             0
00:00:00   0.0
00:00:05   2.5
00:00:10   5.5
00:00:15  10.5
00:00:20  15.5
00:00:25  20.5
00:00:30  25.5
00:00:35  30.5
00:00:40  35.5
00:00:45  40.5
00:00:50  45.5
00:00:55  50.5
00:01:00  55.5
00:01:05  60.5
00:01:10  65.5
00:01:15  70.5
00:01:20  75.5
00:01:25  80.5
00:01:30  85.5
00:01:35  90.5

我用以下代码解决了类似的问题:

interval = 5
frames = []
for base in range(interval):
  frame = data.resample(f"{interval}min", base=base).last()
  frames.append(frame)

pd.concat(frames, axis=0).sort_index()

在这里,我创建了5个数据帧,它们以相同的间隔重新采样,但偏移量不同(基本参数)。然后我只需要将它们连接起来并进行排序。通常应该比滚动+重采样(唯一的开销是排序)效率更高。

您是在寻找过去五个日历月(2012年5月:12月、1月、2月、3月、4月)的std,还是有数据的过去五个月(如果缺少2月,比如:11月、12月、1月、3月、4月)的std?你也提到了包括May,但这没有意义,除非你是指前四个月+MTD(在这种情况下,我的问题仍然存在)我有点难以理解。示例中的目标是调用从1月1日到5月31日的每日值,计算这些值的stdev,并将其作为5月的值返回吗?澄清一下:我正在寻找5个日历月(数据不一定均匀分布),包括当前月份,因此对于2012年5月,我从2012年1月到2012年5月(窗户的长度为5个月,无论我每月只有一天还是20天).User@user3823992是正确的,此外,我只关心每月的结果,因此我需要对2012年6月、2012年7月等应用相同的结果。如果pandas已导入您的日期和时间数据,您应该能够使用语法
dft[datetime(2013,1,1):datetime(2013,6)]
。只需编写一个循环或等效程序,循环开始和结束月份的值,并将您的函数应用于生成的数据帧中的值即可。(对不起,我手头上没有日期戳数据集,无法亲自测试)
In [222]: df_m.groupby('value').sum()
Out[222]: 
              a
value          
2000-09-01   31
2000-10-01   59
2000-11-01   90
2000-12-01  120
2001-01-01  151
2001-02-01  150
2001-03-01  153
2001-04-01  153
2001-05-01  153
2001-06-01  153
2001-07-01  153
...
df = pd.DataFrame(range(0,100), index=pd.TimedeltaIndex(range(0,100),'s'))
df.rolling('10s').mean().resample('5s').first()
             0
00:00:00   0.0
00:00:05   2.5
00:00:10   5.5
00:00:15  10.5
00:00:20  15.5
00:00:25  20.5
00:00:30  25.5
00:00:35  30.5
00:00:40  35.5
00:00:45  40.5
00:00:50  45.5
00:00:55  50.5
00:01:00  55.5
00:01:05  60.5
00:01:10  65.5
00:01:15  70.5
00:01:20  75.5
00:01:25  80.5
00:01:30  85.5
00:01:35  90.5
interval = 5
frames = []
for base in range(interval):
  frame = data.resample(f"{interval}min", base=base).last()
  frames.append(frame)

pd.concat(frames, axis=0).sort_index()