移动窗口函数
移动窗口函数可以理解为时FIR滤波器,只不过这里是滤波器在运动,而不是信号在运动。但是从相对运动的角度来说,移动窗口函数就是FIR滤波器
数据样例
载入一个时间序列,并且按照工作日频率进行重新采样。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# %matplotlib inline
close_px_all = pd.read_csv("data/stock_px_2.csv")
close_px_all.head()
Unnamed: 0 | AAPL | MSFT | XOM | SPX | |
---|---|---|---|---|---|
0 | 2003-01-02 00:00:00 | 7.40 | 21.11 | 29.22 | 909.03 |
1 | 2003-01-03 00:00:00 | 7.45 | 21.14 | 29.24 | 908.59 |
2 | 2003-01-06 00:00:00 | 7.45 | 21.52 | 29.96 | 929.01 |
3 | 2003-01-07 00:00:00 | 7.43 | 21.93 | 28.95 | 922.93 |
4 | 2003-01-08 00:00:00 | 7.28 | 21.31 | 28.83 | 909.93 |
# 简单检查日期是否存在重复值, 确保数据汇总到day这个级别
_date_col = close_px_all.iloc[0,:]
if len(_date_col) == _date_col.nunique():
print("没有日期重复")
else:
print("存在日期重复")
没有日期重复
# 缺失值查看: 全为零,没有缺失值
close_px_all.isnull().sum()
Unnamed: 0 0
AAPL 0
MSFT 0
XOM 0
SPX 0
dtype: int64
close_px_all = pd.read_csv("data/stock_px_2.csv",
parse_dates=True, # -> 自动解析日期,不需要专门指定日期的字符串格式
index_col=0) # -> 0列作为索引列
close_px = close_px_all[['AAPL', 'MSFT', 'XOM']] # -> AAPL:苹果,MSFT:微软,XOM:埃克森美孚
close_px = close_px.resample('B').ffill() # -> 按照工作日频率进行重新采样
# 查看苹果股价
close_px.AAPL.plot()
plt.show()
图1 苹果股价
250日移动窗口平均值
均值滤波,滤波器的长度为250天
appl_mean250 = close_px.AAPL.rolling(250).mean()
close_px.AAPL.plot()
appl_mean250.plot()
plt.legend(['raw', 'mean-250'])
plt.show()
图2 平均滤波和原始数据
仔细观察上图可以发现,橙色的部分有一段是没有值的。这个是由于序列前249个值长度小于移动窗口(250),无法进行这个窗口下的均值计算,所以这种情形下的移动窗口计算结果的序列长度要小于原序列长度。
appl_mean250[:249] # -> 前 249 个值为nan
2003-01-02 NaN
2003-01-03 NaN
2003-01-06 NaN
2003-01-07 NaN
2003-01-08 NaN
..
2003-12-10 NaN
2003-12-11 NaN
2003-12-12 NaN
2003-12-15 NaN
2003-12-16 NaN
Freq: B, Name: AAPL, Length: 249, dtype: float64
参考FIR滤波器的内容,可以通过序列头部补零来确保移动窗口计算前后的序列长度保持一致。