簡體   English   中英

計算 Pandas 中的滾動 beta

[英]Calculating rolling beta in Pandas

我正在嘗試計算 Pandas 中兩個系列之間的滾動測試版。

我的理解是,要獲得 beta,我需要獲得協方差矩陣,然后將單元格 (0, 1) 除以 (1, 1)

所以我創建了一個 function:

def calc_beta (A, B) :

    covariance = np.cov (A, B)     
    beta = covariance[0, 1] / covariance[1, 1]

    return beta

如果我只想為整個系列運行它,我會這樣做:

calc_beta(A, B)

但我不確定如何在滾動的基礎上做到這一點,我嘗試A.rolling(10).apply(calc_beta, raw=False, B)但沒有成功。

然后我只是嘗試滾動計算 cov 矩陣,我可以這樣做:

A = pd.Series(np.random.randint(1,101,50))
B = pd.Series(np.random.randint(1,101,50))

df = pd.DataFrame([A, B]).transpose()
df.rolling(10).cov(df, pairwise=True)

現在我有一個協方差矩陣,但我如何在滾動的基礎上執行 beta 計算,即(covariance[0,1]/covariance[1,1]) (然后得到平均值)。

它可能不是最好的答案(閱讀,最緊湊的)但我認為這可以解決問題。 你實際上是在正確的軌道上開始。 所以,假設你有你給的兩個系列,並將它們制作成 df

A = pd.Series(np.random.randint(1,101,50))
B = pd.Series(np.random.randint(1,101,50))
df = pd.concat([A, B], axis=1)

按以下方式定義 beta 和滾動:

def calc_beta(df):
    np_array = df.values
    s = np_array[:,0] 
    m = np_array[:,1]

    covariance = np.cov(s,m) 
    beta = covariance[0,1]/covariance[1,1]
    return beta

def rolling(df, period, function , min_periods=None):
    if min_periods is None:
        min_periods = period
    result = pd.Series(np.nan, index=df.index)

    for i in range(1, len(df)+1):
        df2 = df.iloc[max(i-period, 0):i,:] #I edited here
        if len(df2) >= min_periods:
            idx = df2.index[-1]
            result[idx] = function(df2)
    return result

並執行以下操作:

calc_beta(df)

返回0.15350171576854774

rolling(df, 12,calc_beta, min_periods=None)

(當然,你可以選擇任何時期)這給

0          NaN
1          NaN
2          NaN
3          NaN
4          NaN
5          NaN
6          NaN
7          NaN
8          NaN
9          NaN
10         NaN
11    0.034478
12    0.019883
13   -0.093483
14    0.140603
15    0.137694
16   -0.004115
17   -0.144355
18   -0.079803
19   -0.023759
20    0.099539
21    0.186670
22    0.199526
23    0.113457
24    0.152232
25    0.149928
26    0.079760
27    0.032097
28    0.056294
29    0.070176
30    0.076560
31    0.013778
32    0.080279
33    0.058864
34    0.006916
35    0.303566
36    0.133580
37    0.238668
38    0.312243
39    0.406835
40    0.337503
41    0.370470
42    0.237132
43    0.253779
44    0.160348
45    0.103425
46    0.261430
47    0.130407
48    0.314028
49    0.322890
dtype: float64

所以我很欣賞@Serge 的回答,但我覺得我可以用一種更簡潔的方式來做。 這就是我想出的對我有用的東西。 如果您對此有任何意見,請告訴我。 再次感謝。

A = pd.Series(np.random.randint(1,101,50))
B = pd.Series(np.random.randint(1,101,50))

df = pd.DataFrame({'A' : A, 'B' : B})
df.rolling(10).cov(df, pairwise=True).drop(['A'], axis=1) \
                        .unstack(1) \
                        .droplevel(0, axis=1) \
                        .apply(lambda row: row['A'] / row['B'], axis=1) \
                        .mean()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM