新手發(fā)文,歡迎拍磚。
聊一下python開(kāi)源包pandas中rolling的使用。
緣起
參加了萬(wàn)礦網(wǎng)舉辦的WQFA初級(jí)認(rèn)證-12月編程考試,有題如下:
???????獲取2016年01月04日至2018年8月30日,RB.SHF和HC.SHF的日漲跌幅數(shù)據(jù),按以下公式,計(jì)算螺紋鋼主力合約RB.SHF與熱卷主力合約HC.SHF每日漲跌幅的滾動(dòng)回歸系數(shù)(每120日的數(shù)據(jù)回歸一次) :
???????一看到“滾動(dòng)”兩個(gè)字,第一反應(yīng)就是用rolling()。想都沒(méi)有想面對(duì)的是DataFrame,而不是Series。
???????先把代碼放上來(lái),獻(xiàn)丑了。
代碼
import statsmodels.api as sm
def answer_question2():
# 第2題代碼寫(xiě)在這里
_, p_close = w.wsd(['RB.SHF', 'HC.SHF'], 'close', '20160104', '20180830', usedf=True)
pct = p_close.pct_change().iloc[1: , :] # 首行為NaN,去除
rb_shf = pct['RB.SHF']
hc_shf = pct['HC.SHF']
# 全局變量,保存滾動(dòng)回歸后的截距
global_alpha = []
def rolling_ols(rb):
'''
滾動(dòng)回歸,返回滾動(dòng)回歸后的回歸系數(shù)
rb: 因變量序列
'''
# 數(shù)據(jù)預(yù)處理
rb.name = 'RB.SHF'
df = pd.concat([rb, hc_shf], axis=1) # 方便index對(duì)齊
df.dropna(inplace=True)
# 回歸
X = sm.add_constant(df['HC.SHF'])
model = sm.OLS(df['RB.SHF'], X)
results = model.fit()
# 結(jié)果輸出
global_alpha.append(results.params['const'])
return results.params['HC.SHF']
# 滾動(dòng)回歸
beta = rb_shf.rolling(120).apply(rolling_ols, raw=False)
# 調(diào)整結(jié)果輸出格式
beta.dropna(inplace=True)
beta.name = 'beta'
global_alpha = pd.Series(global_alpha, index=beta.index, name='alpha')
res = pd.concat([global_alpha, beta], axis=1)
return res
ans2 = answer_question2()
print(ans2)
解析
- rolling就是滾動(dòng)窗口統(tǒng)計(jì)的函數(shù),最主要的參數(shù)就是窗口的寬度,本題中為120;
- 在解決本題時(shí),發(fā)現(xiàn)rolling對(duì)Series對(duì)象較友好,能保持原來(lái)的index;
- 而如果是對(duì)DataFrame對(duì)象進(jìn)行rolling操作的話(huà),會(huì)將整個(gè)DataFrame拉直為Series看待,同時(shí)丟棄掉了index信息;
- 所以本文借用了index對(duì)齊的功能,間接實(shí)現(xiàn)了對(duì)二維數(shù)據(jù)的滾動(dòng)(rolling)操作。
小結(jié)
???????第一次發(fā)簡(jiǎn)書(shū),歡迎大家指正和交流。本文采用了取巧的方法,避免了寫(xiě)for循環(huán),但是終究是奇巧淫技,能夠熟練地看文檔,才是正途。同時(shí)獻(xiàn)上官方參考答案,以供對(duì)比學(xué)習(xí)。感謝萬(wàn)礦提供這樣一個(gè)學(xué)習(xí)和共享的平臺(tái)。