计算一个DataFrame的所有列与另一个DataFrame的所有列之间的相关性?

15

我有一个DataFrame对象股票,其中填充了股票收益率。我有另一个DataFrame对象行业,其中填充了行业回报率。我想找到每个股票与每个行业的相关性。

import numpy as np
np.random.seed(123)

df1=pd.DataFrame( {'s1':np.random.randn(10000), 's2':np.random.randn(10000) } )
df2=pd.DataFrame( {'i1':np.random.randn(10000), 'i2':np.random.randn(10000) } )

这种昂贵的方法是将两个DataFrame对象合并,计算相关性,然后丢掉所有股票与股票之间以及行业与行业之间的相关性。有更有效的方法吗?


这样做的代价很高,有没有更高效的方法呢?
4个回答

25

这里有一个使用apply在列上避免嵌套的for循环的单行代码。主要好处是apply可以在DataFrame中构建结果。

df1.apply(lambda s: df2.corrwith(s))

6

以下是比 @JohnE 更为简单的答案,使用 pandas 原生方法而非使用 numpy.corrcoef。另外一个额外的好处是,你无需从愚蠢的 2x2 相关矩阵中查找相关值,因为 pandas 的系列对系列相关函数只返回一个数字,而不是一个矩阵。

for s in ['s1','s2']:
    for i in ['i1','i2']:
        print df1[s].corr(df2[i])

这并不像@ytsaig的代码那么简单,但是在我进行了一些快速计时后,大约快了5倍,如果您需要更快的解决方案,您应该考虑采用这个答案。 - JohnE

5

添加说明: 我将保留这个答案以供后人参考,但我建议使用后面的答案。特别是,如果你想要最简单的答案,请使用 @ytsaig 的答案;但如果你想要更快的答案(在我使用 OP 数据进行快速计时时,@failwhales 的答案似乎比 @ytsaig 的答案快了约 5 倍,并且与我的答案速度大致相同),请使用 @failwhales 的答案。

原始答案: 你可以使用 numpy.corrcoef(),它基本上与 pandas 中的 corr 相同,但其语法可能更适合你的需求。

for s in ['s1','s2']:
    for i in ['i1','i2']:
        print( 'corrcoef',s,i,np.corrcoef(df1[s],df2[i])[0,1] )
   

打印输出:

corrcoef s1 i1 -0.00416977553597
corrcoef s1 i2 -0.0096393047035
corrcoef s2 i1 -0.026278689352
corrcoef s2 i2 -0.00402030582064

或者您可以将结果加载到带有适当标签的数据框中:

cc = pd.DataFrame()     
for s in ['s1','s2']:
    for i in ['i1','i2']:
        cc = cc.append( pd.DataFrame(
             { 'corrcoef':np.corrcoef(df1[s],df2[i])[0,1] }, index=[s+'_'+i]))

这是它的外观:

       corrcoef
s1_i1 -0.004170
s1_i2 -0.009639
s2_i1 -0.026279
s2_i2 -0.004020

0

虽然有点晚,但是这是更加通用的解决方案:

def corrmatrix(df1,df2):
    s = df1.values.shape[1]
    cr = np.corrcoef(df1.values.T,df2.values.T)[s:,:s]    
    return pd.DataFrame(cr,index = df2.columns,columns = df1.columns)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接