参数
window、min_period、center、closed、win_type、method、axis
window
对于dataframe,window的用法是输入一个int型或者offset,以下以int类型为例
就是在默认axis=0、center=False时,如果window=n,就从第一行开始,每行取自己和前面n-1个数据,然后这几行就成了一个窗口(window),然后就可以对每个窗口进行一些像sum、mean的操作,比如先建立这样一个dataframe
df = pd.DataFrame({'A': [1, 2, 3, 4, 5], 'B': [2, 3, 4, 5, 6], 'C':[3, 4, 5, 6, 7], 'D': [4, 5, 6, 7, 8], 'E': [5, 6, 7, 8, 9]})
A B C D E
0 1 2 3 4 5
1 2 3 4 5 6
2 3 4 5 6 7
3 4 5 6 7 8
4 5 6 7 8 9
然后对他rolling,会返回一个这个
print(df.rolling(window = 1))
Rolling [window=1,center=False,axis=0,method=single]
其中window是必须输入的,像center会默认False,axis默认为0,metho默认single
然后可以对他进行一些操作比如sum,因为window是1,所以就会将0行,1行,2行···单独作为一个窗口,然后让这个窗口的数据进行相加(是以垂直方向的相加),因此得到的结果和原dataframe一样,如下
print(df.rolling(window = 1, min_periods = 1).sum())
A B C D E
0 1.0 2.0 3.0 4.0 5.0
1 2.0 3.0 4.0 5.0 6.0
2 3.0 4.0 5.0 6.0 7.0
3 4.0 5.0 6.0 7.0 8.0
4 5.0 6.0 7.0 8.0 9.0
但如果window是2,因为min_periods默认和window一致,那么会将0行和0行前面那一行作为一个窗口,1行和0行作为一个窗口,2行和1行作为一个窗口···又因为0行前面那一行不存在,所以第一个窗口sum时就会得到NaN,然后存在0行,而第二个窗口1行和0行相加得到3,5,7,9,11,就存在1行,以此类推,如下
print(df.rolling(window = 2).sum())
0 NaN NaN NaN NaN NaN
1 3.0 5.0 7.0 9.0 11.0
2 5.0 7.0 9.0 11.0 13.0
3 7.0 9.0 11.0 13.0 15.0
4 9.0 11.0 13.0 15.0 17.0
同理,window=3时,因为第一个窗口和第二个窗口都存在没有的行(就是第一个窗口是0行和0行前面那两行,然后只有0行存在),所以得到的结果0行和1行都是NaN
print(df.rolling(window = 3).sum())
A B C D E
0 NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN
2 6.0 9.0 12.0 15.0 18.0
3 9.0 12.0 15.0 18.0 21.0
4 12.0 15.0 18.0 21.0 24.0
min_periods
这个参数是指一个窗口内的统计数据的数量,并且默认和window一样大,自己输入的话,是不允许输入大于window的数的
比如window=3时输入min_periods=1,那么他一行一行组成窗口时,就不会把不存在的行算进去,
还是原来那个dataframe,例如有
print(df.rolling(window = 3, min_periods = 1).sum())
因为min_periods是1,就是组成窗口下限是1行,就会从0行开始依次组成窗口长度3的窗口,但是发现0行前面没行了,然后又发现min_periods=1,那就干脆就找一行吧,他就只让0行自己组成了窗口,然后进了1行,发现1行前面只有0行,还是组不成3行的窗口长度,因为min_periods=1,就干脆把这两行组成一个窗口···结果如下
A B C D E
0 1.0 2.0 3.0 4.0 5.0
1 3.0 5.0 7.0 9.0 11.0
2 6.0 9.0 12.0 15.0 18.0
3 9.0 12.0 15.0 18.0 21.0
4 12.0 15.0 18.0 21.0 24.0
要是mean操作的话,也只会对第一个窗口按一行求均值,而不会按三行,如下
print(df.rolling(window = 3, min_periods = 1).mean())
A B C D E
0 1.0 2.0 3.0 4.0 5.0
1 1.5 2.5 3.5 4.5 5.5
2 2.0 3.0 4.0 5.0 6.0
3 3.0 4.0 5.0 6.0 7.0
4 4.0 5.0 6.0 7.0 8.0
以A列为例,0行就是1/1,1行结果是(1+3)/2
center
以上都是把自己这一行和前面的行组成一个窗口,如果输入center=True,那么会以自己这一行为中心,与前后行共同组成一个窗口
比如
print(df.rolling(window = 3, min_periods = 3, center = True).sum())
结果就是
A B C D E
0 NaN NaN NaN NaN NaN
1 6.0 9.0 12.0 15.0 18.0
2 9.0 12.0 15.0 18.0 21.0
3 12.0 15.0 18.0 21.0 24.0
4 NaN NaN NaN NaN NaN
为什么0行和4行都是NaN呢?就是因为center=True,min_periods还等于3,然后组成窗口时,0行就会取自己前面那一行和自己后面那一行来组建窗口,但前面没有行了,所以sum操作时就产生NaN行放在0行上面,而4行为NaN是因为组建窗口时,取3行和自己后面那一行来组建,但自己后面没了,所以也为NaN
axis
默认axis=0,但如果输入axis=1,其实效果无非是由行换成了列,比如还是最开始那个dataframe
有如下操作
print(df.rolling(window = 1, min_periods = 1, axis = 1).sum())
print(df.rolling(window = 2, min_periods = 2, axis = 1).sum())
print(df.rolling(window = 3, min_periods = 2, axis = 1).sum())
结果分别为
A B C D E
0 1.0 2.0 3.0 4.0 5.0
1 2.0 3.0 4.0 5.0 6.0
2 3.0 4.0 5.0 6.0 7.0
3 4.0 5.0 6.0 7.0 8.0
4 5.0 6.0 7.0 8.0 9.0
A B C D E
0 NaN 3.0 5.0 7.0 9.0
1 NaN 5.0 7.0 9.0 11.0
2 NaN 7.0 9.0 11.0 13.0
3 NaN 9.0 11.0 13.0 15.0
4 NaN 11.0 13.0 15.0 17.0
A B C D E
0 NaN 3.0 6.0 9.0 12.0
1 NaN 5.0 9.0 12.0 15.0
2 NaN 7.0 12.0 15.0 18.0
3 NaN 9.0 15.0 18.0 21.0
4 NaN 11.0 18.0 21.0 24.0
对groupby类型
无论是seriesgroupby还是dataframegroupby,都会对每个group分别做rolling,每个group不会干扰,比如
df = pd.DataFrame({'group': list('aabbabbbabab'),
'value': [1, 2, 3, np.nan, 2, 3, np.nan, 1, 7, 3, np.nan, 8]})
g1 = df.groupby(['group'])['value']
for i in g1:
print(i)
print(g1.rolling(2, min_periods = 2).sum())
('a', 0 1.0
1 2.0
4 2.0
8 7.0
10 NaN
Name: value, dtype: float64)
('b', 2 3.0
3 NaN
5 3.0
6 NaN
7 1.0
9 3.0
11 8.0
Name: value, dtype: float64)
group
a 0 NaN
1 3.0
4 4.0
8 9.0
10 NaN
b 2 NaN
3 NaN
5 NaN
6 NaN
7 NaN
9 4.0
11 11.0
由于a组0行和b组2行前面都没有行了,但窗口长度和min_periods都是2,所以产生的结果中,a组0行和b组2行都是NaN