窗函數(window function)經常用在頻域信號分析中。我其實不咋個懂,大概是從無限長的信號中截一段出來,然後把這一段做延拓變成一個虛擬的無限長的信號。用來截取的函數就叫窗函數,窗函數又分很多種,什麼矩形窗、三角窗、高斯窗。 在scipy.signal中有各種我不懂的實現窗函數的方法。瀏覽了 ...
窗函數(window function)經常用在頻域信號分析中。我其實不咋個懂,大概是從無限長的信號中截一段出來,然後把這一段做延拓變成一個虛擬的無限長的信號。用來截取的函數就叫窗函數,窗函數又分很多種,什麼矩形窗、三角窗、高斯窗。
在scipy.signal中有各種我不懂的實現窗函數的方法。瀏覽了一下,頭疼的緊。
那在pandas中也有實現窗函數的方法:rolling()
。我呢就不折騰什麼信號處理的東西,用金融數據做個小示例好了。
金融時間序列也是一種時間序列數據,前後次序是固定,多為二維數據。例如要看一隻股票的平均移動線,就會用到rolling()
。
先介紹一下這個翻滾函數
DataFrame.rolling(window,
min_periods=None,
freq=None,
center=False,
win_type=None,
on=None,
axis=0)
-
window
: 移動視窗的大小。值可以是int(整數值)或offset(偏移)。如果是整數值的話,每個視窗是固定的大小,即包含相同數量的觀測值。值為offset(偏移時長,eg:'2s'
)則指定了每個視窗包含的時間段,每個視窗包含的觀測值的數量是不一定的。offset必須在index是時間類型數據時才可以使用。 -
min_periods
: 每個視窗最少包含的觀測值數量,小於這個值的視窗結果為NA。值可以是int,預設None。offset情況下,預設為1。 -
freq
: 棄用。不用管它。 -
center
: 把視窗的標簽設置為居中。布爾型,預設False,居右。 -
win_type
: 視窗的類型。上面介紹的,截取窗的各種函數。字元串類型,預設為None。可用的視窗類型有:- boxcar
- triang
- blackman
- hamming
- bartlett
- parzen
- bohman
- blackmanharris
- nuttall
- barthann
- kaiser (needs beta)
- gaussian (needs std)
- general_gaussian (needs power, width)
- slepian (needs width)
-
on
: 可選參數。對於dataframe而言,指定要計算滾動視窗的列。值為列名。 -
axis
: int、字元串,預設為0,即對列進行計算。
使用方法,例:
In []: df = pd.DataFrame({'B': [0, 1, 2, np.nan, 4]})
In []: df.rolling(2).sum()
Out[]:
B
0 NaN
1 1.0
2 3.0
3 NaN
4 NaN
按tab鍵可以查看rolling對象可用的方法,如下:
In []: r = df.rolling(2)
In []: r
Out[]: Rolling [window=10,center=False,axis=0]
In []: r.
r.agg r.cov r.max r.ndim
r.aggregate r.exclusions r.mean r.quantile
r.apply r.is_datetimelike r.median r.skew
r.corr r.is_freq_type r.min r.std
r.count r.kurt r.name r.sum
註:
rolling_mean()
這種寫法已經淘汰了,現在都是df.rolling().mean()
、df.rolling().std()
這樣來寫。
例:計算蘋果收盤價的平均移動線
獲取數據
從雅虎獲取蘋果公司2016年1月1日至今的股票數據。
import pandas_datareader.data as web
apple = web.DataReader(name='AAPL',
data_source='yahoo',
start='2016-1-1')
print(apple.head())
數據大概是這個樣子的:
Open High Low Close Volume \
Date
2016-01-04 102.610001 105.370003 102.000000 105.349998 67649400
2016-01-05 105.750000 105.849998 102.410004 102.709999 55791000
2016-01-06 100.559998 102.370003 99.870003 100.699997 68457400
2016-01-07 98.680000 100.129997 96.430000 96.449997 81094400
2016-01-08 98.550003 99.110001 96.760002 96.959999 70798000
Adj Close
Date
2016-01-04 103.057063
2016-01-05 100.474523
2016-01-06 98.508268
2016-01-07 94.350769
2016-01-08 94.849671
收盤價的折線圖
為了方便觀察滾完了之後的效果,我們把數據都畫圖呈現出來。
apple['Close'].plot(figsize=(9, 5), grid=True)
plt.show()
收盤價
平均移動線MA
apple['roll_mean'] = apple['Close'].rolling(window=5).mean()
apple[['Close', 'roll_mean']].plot(subplots=True, figsize=(9, 5), grid=True)
plt.show()
收盤價和5日平均移動線
這裡視窗大小為5,所以前面四個數據是沒有值的。把它們合在一起看看(把subplots改為False)。
收盤價和5日平均移動線合在一起拉近一點:
直觀上看更平滑了。畢竟取五天做平均了,第一天漲第二天跌的這種一平均波動就小了。如果視窗變大會更平滑。
windowsize = [5,10,20]
for i in windowsize:
apple['roll_mean_'+str(i)] = apple['Close'].rolling(i).mean()
apple[['roll_mean_5','roll_mean_10','roll_mean_20']].plot(figsize=(9, 5), grid=True)
plt.show()
補充
除了算平均值,還可以計算方差、相關、最大最小值等等,大部分的統計量都可以計算,就看你需要了。
另外如果已有的函數不能滿足需要,我們還可以用lambda
和apply()
寫自己的方法。
例如(直接複製官網的咯):
mad = lambda x: np.fabs(x - x.mean()).mean()
apple['Close'].rolling(window=5).apply(mad).plot(figsize=(9, 5), grid=True)
plt.show()
這裡計算的是平均絕對偏差。
我的圖長得漂亮是因為安裝了seaborn庫,畫圖之前悄悄載入了一下。
另外,pandas中也有好些金融函數,比如計算指數加權移動平均,就現成的
pandas.ewma()
。待挖掘的東西好多呢。
作者:ChZ_CC
鏈接:https://www.jianshu.com/p/f6e489de57f7
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。