2017-10-12 67 views
2

我有兩個數據框,每列200列。爲了說明,我在這裏只使用3列。查找數據框中相應列的相關性

數據幀DF1爲:

  A B C 
1/4/2017 5 6 6 
1/5/2017 5 2 1 
1/6/2017 6 2 10 
1/9/2017 1 9 10 
1/10/2017 6 6 4 
1/11/2017 6 1 1 
1/12/2017 1 7 10 
1/13/2017 8 9 6 

數據幀DF2:

  A D B 
1/4/2017 8 10 2 
1/5/2017 2 1 8 
1/6/2017 6 6 6 
1/9/2017 1 8 1 
1/10/2017 10 6 2 
1/11/2017 10 2 4 
1/12/2017 5 4 10 
1/13/2017 5 2 8 

我要計算的下列相關矩陣爲df1df2對應列:使用

  A  B 
1/4/2017   
1/5/2017   
1/6/2017 0.19 -0.94 
1/9/2017 0.79 -0.96 
1/10/2017 0.90 -0.97 
1/11/2017 1.00 -1.00 
1/12/2017 1.00 0.42 
1/13/2017 0.24 0.84 

即追蹤同一列的3天曆史數據和df2,我需要找到相關矩陣。

所以,我計算corr([5, 5, 6], [8, 2, 6]) = 0.19其中[5,5,6]df1['A'][8,2,6]df2['A']

因爲,我有200列,每列我發現它非常麻煩運行一個for循環兩次。首先循環遍歷列,然後使用尾隨3天滯後數據。

回答

4

這是你所需要的?

l=[] 
id=df1.columns.intersection(df2.columns) 
for x in id: 
    l.append(pd.rolling_corr(df1[x],df2[x],window=3))# notice you should change it to `l.append(df1[x].rolling(3).corr(df2[x]))` 

pd.concat(l,axis=1) 


Out[13]: 
        A   B 
1/4/2017  NaN  NaN 
1/5/2017  NaN  NaN 
1/6/2017 0.188982 -0.944911 
1/9/2017 0.785714 -0.960769 
1/10/2017 0.896258 -0.968620 
1/11/2017 1.000000 -0.998906 
1/12/2017 1.000000 0.423415 
1/13/2017 0.240192 0.838628 
+0

您可能會喜歡我發佈的第二個選項。 – piRSquared

+0

@piRSquared看看,總是喜歡學習numpy的方法!! 1 – Wen

3

選項1
我建立了一個發生器和包裹在pd.concat

def rolling_corrwith(d1, d2, window): 
    d1, d2 = d1.align(d2, 'inner') 
    for i in range(len(d1) - window + 1): 
     j = i + window 
     yield d1.iloc[i:j].corrwith(d2.iloc[i:j]).rename(d1.index[j-1]) 

pd.concat(list(rolling_corrwith(df1, df2, 3)), axis=1).T 

        A   B 
1/6/2017 0.188982 -0.944911 
1/9/2017 0.785714 -0.960769 
1/10/2017 0.896258 -0.968620 
1/11/2017 1.000000 -0.998906 
1/12/2017 1.000000 0.423415 
1/13/2017 0.240192 0.838628 

選項2
使用numpy的進展。我不推薦這種方法。但值得一提的是那些有興趣的人。

from numpy.lib.stride_tricks import as_strided as strided 

def sprp(v, w): 
    s0, s1 = v.strides 
    n, m = v.shape 
    return strided(v, (n + 1 - w, w, m), (s0, s0, s1)) 

def rolling_corrwith2(d1, d2, window): 
    d1, d2 = d1.align(d2, 'inner') 

    s1 = sprp(d1.values, window) 
    s2 = sprp(d2.values, window) 

    m1 = s1.mean(1, keepdims=1) 
    m2 = s2.mean(1, keepdims=1) 
    z1 = s1.std(1) 
    z2 = s2.std(1) 

    c = ((s1 - m1) * (s2 - m2)).sum(1)/z1/z2/window 

    return pd.DataFrame(c, d1.index[window - 1:], d1.columns) 

rolling_corrwith2(df1, df2, 3) 

        A   B 
1/6/2017 0.188982 -0.944911 
1/9/2017 0.785714 -0.960769 
1/10/2017 0.896258 -0.968620 
1/11/2017 1.000000 -0.998906 
1/12/2017 1.000000 0.423415 
1/13/2017 0.240192 0.838628