pandas实现多行多列窗口移动

原生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

直接在函数调用外部的数据,虽然不够合理,但也是一种解决办法。