假设有10天的销售数据,我们要每三天计算一次总和,比如第五天的总和就是第三天的销售额总和+第四天+第五天还有,这个时候我们该怎么办呢?Series对象有一个rolling方法,专门用于移动计算。让我们来看看。将熊猫导入为pdamount=pd.Series([100,90,110,150,110,130,80,90,100,150])print(amount.rolling(3).sum())"""0NaN#NaN+NaN+1001NaN#NaN+100+902300.0#100+90+1103350.0#90+110+1504370.0#110+150+1105390.0#150+110+130630.0+3030#0+908270.0#80+90+1009340.0#90+100+150dtype:float64"""结果和我们想要的一样,amount.rolling(3)相当于创建一个长度为3的窗口,window从上往下滑动,我们画了一张图:amount.rolling(3)做了类似图片的事情,然后在它的基础上调用sum,会把每个window里面的元素累加起来,也就是Getthe以上代码的输出。另外,窗口的大小可以是任意的,这里我们以3为例。除了求和,还可以计算平均值,计算方差等,可以进行很多操作。如果你有兴趣,你可以自己尝试一下。当然我们也可以自定义函数:importpandasaspdimportnumpyasnpamount=pd.Series([100,90,110,150,110,130,80,90,100,150])print(#调用aggmethod,passAfunction#参数x为每个窗口中元素组成的Series对象amount.rolling(3).agg(lambdax:np.sum(x)*2))"""0NaN#(NaN+NaN+100(150+110+130)*26640.0#(110+130+80)*27600.0#(130+80+90)*28540.0#(80+90+100)*29680.0#(90+100)+150)*2dtype:float64"""agg中函数的逻辑可以是任意的,但是返回必须是一个值。另外,我们注意到前两个元素是NaN,这是因为rolling(3)的意思从当前位置往上过滤,一共筛选出3个元素,图中已经画的很清楚了,但是如果元素不够,我们要统计多少个元素呢?例如:元素之和第一个窗口中的是第一个元素,第一个窗口中的元素之和第二个窗口是第一个元素加上第二个元素。importpandasaspdamount=pd.Series([100,90,110,150,110,130,80,90,100,150])print(#min_periods表示窗口的最小观测值amount.rolling(3,min_periods=1).sum())"""0100.01190.02300.03350.04370.05390.06320.07300.08270.09340.0dtype:float64"""可以通过加一个min_periods参数来实现,min_periods代表窗口的最小观测值,即,窗口中元素的最小数量,默认等于窗口的长度。我们的窗口长度是3,但是min_periods指定为1,也就是说元素不够没有关系,只要有一个就可以了。因此,如果没有足够的元素,有几个。如果我们将min_periods指定为2会怎样?很明显第一个是NaN,第二个还是190.0,因为窗口的元素个数至少是2个。importpandasaspdamount=pd.Series([100,90,110,150,110,130,80,90,100,150])print(#窗口的最小观测值为2amount.rolling(3,min_periods=2).sum())"""0NaN1190.02300.03350.04370.05390.06320.07300.08270.09340.0dtype:float64"""注意:min_periods必须小于等于窗口长度,否则会报错。rolling中还有一个center参数,默认为False。我们知道rolling(3)的意思是从当前元素开始往上过滤,再加上它自己一共过滤3个元素。但是如果center指定为True,则当前元素将居中并从两个方向进行过滤。比如rolling(3,center=True),那么会向上选一个,向下选一个,一共3个。所以原理图看起来像这样:让我们来测试一下:importpandasaspdamount=pd.Series([100,90,110,150,110,130,80,90,100,150])print(amount.rolling(3、center=True).sum())"""0NaN1300.02350.03370.04390.05320.06300.07270.08340.09NaNdtype:float64"""这里没有指定min_periods,最小观测值等于窗口长度,所以滚动(3,center=True)会导致开头为NaN,结尾为NaN。这时候,有些人可能会好奇。如果窗口的长度是奇数,就很简单了。比如长度是9,那么选4向上,4向下,把自己加到刚好9。但是如果窗口的长度是偶数呢?比如长度为8,此时会选择上4下3,加上自己恰好8。另外,我们还可以从上到下过滤,比如窗口长度为3,但是我们要从当前元素开始过滤到底,一共加3来过滤。将熊猫作为ppdf从pandas.api.indexers导入FixedForwardWindowIndexeramount=pd.Series([100,90,110,150,110,130,80,90,100,150])print(amount.rolling(FixedForwardWindowIndexer(window_size=3)).sum())"""0300.01350.02370.03390.04320.05300.06270.07340.08NaN9NaNdtype:float64"""这个可以通过类FixedForwardWindowIndexer来实现,当然此时不能指定center参数。调用amount.rolling()会返回一个Rolling对象,然后调用Rolling对象的sum、max、min、mean、std等方法计算每个窗口的sum、maximum、minimum等。当然我们也可以调用agg方法,传入一个函数来定义每个窗口的计算逻辑。那么重点就是agg除了可以接收一个函数,还可以接收一个列表。列表中可以有多个函数,然后同时执行多个操作。importpandasaspdimportnumpyasnpamount=pd.Series([100,90,110,150,110,130,80,90,100,150])print(amount.rolling(3).agg([np.sum,np.mean,lambdax:np.sum(x)*2]))#Performmultipleoperations,thenaDataFramewillbereturned"""summean
