使用.corr获取两列之间的相关性


127

我有以下熊猫数据框Top15在此处输入图片说明

我创建了一个估计每人可引用文件数量的列:

Top15['PopEst'] = Top15['Energy Supply'] / Top15['Energy Supply per Capita']
Top15['Citable docs per Capita'] = Top15['Citable documents'] / Top15['PopEst']

我想知道人均引用文件数量与人均能源供应之间的相关性。因此,我使用了.corr()方法(皮尔逊相关性):

data = Top15[['Citable docs per Capita','Energy Supply per Capita']]
correlation = data.corr(method='pearson')

我想返回一个数字,但是结果是: 在此处输入图片说明


我想你是对的。但是您能告诉我为什么'data.corr(method ='pearson')'只返回能源供应和能源供应之间的关系吗?
tong zhu

1
它不是。它应该返回一个2x2矩阵;您将显示其左上角的条目。如果.corr直接应用于数据框,它将返回所有成对的相关性;这就是为什么您在矩阵的对角线上观察到1(每个列与自身完全相关)的原因。请参阅下面的编辑。
克莱布(Cleb)

1
如果您认为答案已经回答了您的问题,请考虑接受
MaxU

1
我已经接受了您的回答,谢谢
tong zhu

28
这个问题直接来自Coursera上的“ Python数据科学入门”课程。具体来说,作业3,问题9。当老师克里斯·布鲁克斯(Chris Brooks)鼓励学生向Stack Overflow发布问题时,我认为他的意思不是他们应该逐字逐句地发布问题。
LS

Answers:


209

没有实际数据,很难回答这个问题,但是我想您正在寻找这样的东西:

Top15['Citable docs per Capita'].corr(Top15['Energy Supply per Capita'])

这样就可以计算出两列 'Citable docs per Capita'之间的相关性'Energy Supply per Capita'

举个例子:

import pandas as pd

df = pd.DataFrame({'A': range(4), 'B': [2*i for i in range(4)]})

   A  B
0  0  0
1  1  2
2  2  4
3  3  6

然后

df['A'].corr(df['B'])

给出1预期。

现在,如果您更改一个值,例如

df.loc[2, 'B'] = 4.5

   A    B
0  0  0.0
1  1  2.0
2  2  4.5
3  3  6.0

命令

df['A'].corr(df['B'])

退货

0.99586

仍接近预期的1。

如果.corr直接应用于数据框,它将返回列之间的所有成对关联;这就是为什么您然后1s在矩阵的对角线处进行观察的原因(每列与自身完全相关)。

df.corr()

因此将返回

          A         B
A  1.000000  0.995862
B  0.995862  1.000000

在您显示的图形中,仅表示相关矩阵的左上角(我假设)。

在某些情况下,您可以NaN在解决方案中找到s-请查看示例。

如果要过滤高于或低于特定阈值的条目,可以检查此问题。如果要绘制相关系数的热图,可以检查该答案,如果然后遇到轴标签重叠的问题,请检查以下文章


可以逐行应用吗?
Dr.DOOM '18 -4-3

1
@ Dr.DOOM:是的,它只需要进行序列化,因此例如df.loc[1, :].corr(df.loc[2, :])也可以正常工作。对于整个数据框,您可以简单地转置:df.T.corr()
克莱布'18

我尝试了您的建议,但是即使使用df.loc [2,'B'] = 4.5更改了B列中的a值,计算仍然返回1。也许我只是对计算感到困惑
Dr.DOOM '18

@ Dr.DOOM:很难提供帮助,因为我不知道您的代码。我是否正确理解上述示例返回1了您而不是您 0.99586
克莱布'18

1
@Cleb:好吧,在我工作的环境中,每个更高级别的多列索引都有相同的子层。请参阅以下问题以了解我要做什么:stackoverflow.com/questions/57513002/…–
阿德里安·基斯特

7

我遇到了同样的问题。它似乎Citable Documents per Person是一个浮点数,Python默认以某种方式跳过它。我数据框的所有其他列均为numpy格式,因此我通过将columnt转换为np.float64

Top15['Citable Documents per Person']=np.float64(Top15['Citable Documents per Person'])

请记住,这正是您自己计算的列


6

我的解决方案是将数据转换为数值类型后:

Top15[['Citable docs per Capita','Energy Supply per Capita']].corr()

选择列,然后再进行.corr()方法是,因为我们可以计算多于2列之间的相关性成对一个很好的选择
塞巴斯蒂安温茨科夫斯基

4

如果要在所有成对的列之间建立关联,可以执行以下操作:

import pandas as pd
import numpy as np

def get_corrs(df):
    col_correlations = df.corr()
    col_correlations.loc[:, :] = np.tril(col_correlations, k=-1)
    cor_pairs = col_correlations.stack()
    return cor_pairs.to_dict()

my_corrs = get_corrs(df)
# and the following line to retrieve the single correlation
print(my_corrs[('Citable docs per Capita','Energy Supply per Capita')])

3

当您致电:

data = Top15[['Citable docs per Capita','Energy Supply per Capita']]
correlation = data.corr(method='pearson')

由于DataFrame.corr()函数执行成对关联,因此您需要从两个变量中获得四对。因此,基本上,您会得到对角线值作为自动相关性(与自身相关,两个值,因为您有两个变量),而其他两个值作为一个对另一个的互相关,反之亦然。

在两个序列之间执行相关以获得单个值:

from scipy.stats.stats import pearsonr
docs_col = Top15['Citable docs per Capita'].values
energy_col = Top15['Energy Supply per Capita'].values
corr , _ = pearsonr(docs_col, energy_col)

或者,如果您想从同一函数(DataFrame的corr)中获得一个值:

single_value = correlation[0][1] 

希望这可以帮助。


3

它是这样的:

Top15['Citable docs per Capita']=np.float64(Top15['Citable docs per Capita'])

Top15['Energy Supply per Capita']=np.float64(Top15['Energy Supply per Capita'])

Top15['Energy Supply per Capita'].corr(Top15['Citable docs per Capita'])

1

我通过更改数据类型解决了这个问题。如果您看到“人均能源供应”是数字类型,而“人均城市文档”则是对象类型。我使用astype将列转换为float。我曾与一些NP功能相同的问题:count_nonzerosum合作,同时meanstd没有。


0

在关联之前将“人均Citable docs”更改为数字可以解决该问题。

    Top15['Citable docs per Capita'] = pd.to_numeric(Top15['Citable docs per Capita'])
    data = Top15[['Citable docs per Capita','Energy Supply per Capita']]
    correlation = data.corr(method='pearson')
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.