文章目录
13.1 窗口计算
13.1.1 理解窗口计算
窗口:在一个数列中,选择一部分数据所形成的数据区间。
窗口计算:对很多窗口进行计算得到的结果集成为一个新的数列。
13.1.2 移动窗口 rolling()
移动窗口rolling()创建了一个按一定移动位移动的移动窗口对象,接着可以对每个对象进行统计操作。一个数据可以参与到多个窗口的(集合、分组)中,而groupby中的一个值只能在一个组中
13.1.3 扩展窗口
“扩展”指的是从数据(大多数是时间)的起始处开始窗口,增加窗口到指定大小。一般所有的数据都会参与所有窗口。
13.1.4 指数加权移动
在移动窗口和扩展窗口中,分组中的所有数值的权重都一样,而指数加权移动对分组中的数据给予不同的权重。
Pandas提供了ewm()来实现指数加权移动。
13.2 窗口操作
s.rolling()是移动窗口函数,此函数可以应用于一系列数据,指定窗口数window=n,并在其上调用适合的统计函数。
13.2.1 计算方法
# 原始数据
s = pd.Series(range(1, 7))
# 移动窗口
s.rolling(2).sum()
"""
0 NaN
1 3.0
2 5.0
3 7.0
4 9.0
5 11.0
dtype: float64
"""
13.2.2 基本语法
# 语法
df.rolling(window, min_periods=None, center=False,
win_type=None, on=None, axis=0, closed=None)
- window:必传,如果使用int,可以表示该窗口大小;如果是offset类型,表示时间数据中窗口按此时间偏移量设定大小。
- min_periods:每个窗口的最小数据,小于此值窗口的输出值为NaN,offset情况下,默认为1。默认情况下此值取窗口的大小。
- win_type:窗口类型,默认为加权平均,支持非常丰富的窗口函数,比如boxcar、triang…
- on:可选参数,对于DataFrame要作为窗口的列。
- axis:计算的轴方向
- closed:窗口开闭区间的定义,支持’right’, ‘left’, ‘both’, ‘neighther’。对于offset类型,默认是左开右闭,默认为right。
13.2.3 移动窗口使用
先定义一个时序DataFrame:
df = pd.DataFrame (np.random.randn(30, 4),
index=pd.date_range('10/1/2020', periods=30),
columns=['A', 'B', 'C', 'D'])
"""
A B C D
2020-10-01 -0.314190 -1.844423 -0.483025 -0.171130
2020-10-02 -0.588505 1.053370 -0.421972 1.266176
2020-10-03 0.540665 -0.216484 -0.063941 -0.153170
2020-10-04 -0.187831 0.040709 -0.784140 0.226987
2020-10-05 1.077998 1.255299 -1.180822 0.847738
...
2020-10-26 -1.354728 0.101587 0.331900 -0.228319
2020-10-27 1.052175 0.947007 0.296800 -2.553783
2020-10-28 0.432696 1.239459 1.225046 0.464061
2020-10-29 1.785834 1.241243 0.020836 0.815169
2020-10-30 -0.280711 -1.684375 -0.742894 0.570252
"""
接下来, 以每两天为一个窗口,在窗口上求平均数:
# 每两天一个窗口,求平均数
df.rolling(2).mean()
"""
A B C D
2020-10-01 NaN NaN NaN NaN
2020-10-02 -0.451348 -0.395527 -0.452498 0.547523
...
2020-10-30 0.752562 -0.221566 -0.361029 0.692710
"""
接着,使用时间偏移作为周期,2D代表两天,与上例相同,不过,使用时间偏移的话,默认的最小观察数据为1天,所以第一天也有数据,即它本身。
# 每两天一个窗口,求平均数
df.rolling('2D').mean()
"""
A B C D
2020-10-01 -0.314190 -1.844423 -0.483025 -0.171130
2020-10-02 -0.451348 -0.395527 -0.452498 0.547523
...
2020-10-30 0.752562 -0.221566 -0.361029 0.692710
"""
如果只对一指定列进行窗口计算,可用以下两个方法之一:
# 仅对A列进行窗口计算
df.rolling('2D')['A'].mean() # 方法一
df.A.rolling('2D').mean() # 方法二
使用窗口函数可以指定窗口类型,如汉明(Hamming)窗:
# 使用窗口函数,汉明窗
df.rolling(2, win_type='hamming').sum()
13.2.4 统计方法
窗口主要支持以下统计方法:
- count():非空值数
- sum():值的总和
- mean():平均值
- median():数值的算术中位数
- min():最小值
- max():最大值
- std():贝塞尔校正的样本标准偏差
- var():无偏方差
- skew():样本倾斜度
- kurt():峰度样本
- quantile():样本分位数(百分位上的值)
- cov():无偏协方差(二进制)
- corr():关联(二进制)
13.2.5 agg()
使用agg()可以调用多个函数,多列使用不同函数或者一列使用多个函数。
# 对窗口中的不同列使用不同的计算方法
df.rolling('2D').agg({'A': sum, 'B': np.std})
# 对同一列使用多个函数,同时对不同函数计算出的列命名
df.A.rolling('2D').agg({'A_sum': sum, 'A_std': np.std})
13.2.6 apply()
apply()可以在窗口上实现自定义函数,要求应用此函数后产生一个单一值,因为窗口计算后每个窗口产生的也是唯一值:
# 对窗口求和再加1,最终求绝对值
df.A.rolling('2D').apply(lambda x: abs(sum(x)+1))
13.2.7 扩展窗口
s.expanding()是Pandas扩展窗口的函数,使用逻辑和s.rolling()一样。
区别:
- rolling()窗口大小固定,移动计算;
- expanding()只设置最小可计算量,不固定窗口大小,不断扩展进行计算。
# 原始数据
s = pd.Series(range(1, 7))
# 扩展窗口
s.expanding(2).sum()
"""
0 NaN
1 3.0
2 6.0
3 10.0
4 15.0
5 21.0
dtype: float64
"""
expanding()的窗口每一步都在延伸。