计算一个 DataFrame 的所有列与另一个 DataFrame 的所有列之间的相关性?
Calculate correlation between all columns of a DataFrame and all columns of another DataFrame?
我有一个 DataFrame 对象 stocks
装满了股票 returns。我有另一个 DataFrame 对象 industries
填充了行业 returns。我想找到每个股票与每个行业的相关性。
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 对象,计算相关性,然后抛出所有股票到股票和行业到行业的相关性。有没有更有效的方法来做到这一点?
编辑添加:我会把这个答案留给后代,但会推荐后面的答案。特别是,如果您想要最简单的答案,请使用@ytsaig's,但如果您想要更快的答案,请使用@failwhales's(在我使用 OP 中的数据所做的一些快速计时中,它似乎比@ytsaig's 快 5 倍左右,并且速度与我的)。
原始答案:您可以使用 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
这是一个比@JohnE 更简单的答案,它使用 pandas 本机而不是 numpy.corrcoef。作为额外的好处,您不必从愚蠢的 2x2 相关矩阵中检索相关值,因为 pandas 的系列到系列相关函数只是 returns 一个数字,而不是矩阵.
for s in ['s1','s2']:
for i in ['i1','i2']:
print df1[s].corr(df2[i])
这是一个在列上使用 apply
并避免嵌套 for 循环的单行代码。主要好处是 apply
在 DataFrame 中构建结果。
df1.apply(lambda s: df2.corrwith(s))
很晚,但更通用的解决方案:
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)
我有一个 DataFrame 对象 stocks
装满了股票 returns。我有另一个 DataFrame 对象 industries
填充了行业 returns。我想找到每个股票与每个行业的相关性。
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 对象,计算相关性,然后抛出所有股票到股票和行业到行业的相关性。有没有更有效的方法来做到这一点?
编辑添加:我会把这个答案留给后代,但会推荐后面的答案。特别是,如果您想要最简单的答案,请使用@ytsaig's,但如果您想要更快的答案,请使用@failwhales's(在我使用 OP 中的数据所做的一些快速计时中,它似乎比@ytsaig's 快 5 倍左右,并且速度与我的)。
原始答案:您可以使用 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
这是一个比@JohnE 更简单的答案,它使用 pandas 本机而不是 numpy.corrcoef。作为额外的好处,您不必从愚蠢的 2x2 相关矩阵中检索相关值,因为 pandas 的系列到系列相关函数只是 returns 一个数字,而不是矩阵.
for s in ['s1','s2']:
for i in ['i1','i2']:
print df1[s].corr(df2[i])
这是一个在列上使用 apply
并避免嵌套 for 循环的单行代码。主要好处是 apply
在 DataFrame 中构建结果。
df1.apply(lambda s: df2.corrwith(s))
很晚,但更通用的解决方案:
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)