原生pandas不能实现多行多列的窗口移动。rolling只能应用到1列数据上。
- 先看rolling后的返回的是什么。
>>> d = pd.DataFrame(np.arange(8).reshape(4,2), columns=["a","b"])
>>> da b
0 0 1
1 2 3
2 4 5
3 6 7>>> def check(x):
... print("type:", type(x))
... print("value:", x)
... print("index:", x.index)
... return 1>>> d["a"].rolling(2).apply(lambda x: check(x))
type: <class 'pandas.core.series.Series'>
value: 0 0.0
1 2.0
dtype: float64
index: RangeIndex(start=0, stop=2, step=1)
type: <class 'pandas.core.series.Series'>
value: 1 2.0
2 4.0
dtype: float64
index: RangeIndex(start=1, stop=3, step=1)
type: <class 'pandas.core.series.Series'>
value: 2 4.0
3 6.0
dtype: float64
index: RangeIndex(start=2, stop=4, step=1)
0 NaN
1 1.0
2 1.0
3 1.0
Name: a, dtype: float64
可以看到,rolling传递到函数里的是一个Series。Series的index是RangeIndex类型,其中的start、stop就是rolling窗口的起始index和截至index。
假设求a、b列每2行的总和,可以这样写,
>>> def d_sum(x):
... return d.iloc[x.index.start:x.index.stop].values.sum()>>> d["a"].rolling(2).apply(lambda x: d_sum(x))
0 NaN
1 6.0
2 14.0
3 22.0
Name: a, dtype: float64