如何在Pandas数据框中选择列并进行Pearson相关性分析

27

我有一个长这样的CSV:

gene,stem1,stem2,stem3,b1,b2,b3,special_col
foo,20,10,11,23,22,79,3
bar,17,13,505,12,13,88,1
qui,17,13,5,12,13,88,3

并且作为数据框看起来是这样的:

In [17]: import pandas as pd
In [20]: df = pd.read_table("http://dpaste.com/3PQV3FA.txt",sep=",")
In [21]: df
Out[21]:
  gene  stem1  stem2  stem3  b1  b2  b3  special_col
0  foo     20     10     11  23  22  79            3
1  bar     17     13    505  12  13  88            1
2  qui     17     13      5  12  13  88            3
我想做的是对最后一列(special_col)和gene列与特殊列之间每一列执行Pearson相关性分析,即colnames [1:number_of_column-1]。
最终我们将得到一个长度为6的数据框。
Coln   PearCorr
stem1  0.5
stem2 -0.5
stem3 -0.9999453506011533
b1    0.5
b2    0.5
b3    -0.5

以上数值是手动计算得出的:

In [27]: import scipy.stats
In [39]: scipy.stats.pearsonr([3, 1, 3], [11,505,5])
Out[39]: (-0.9999453506011533, 0.0066556395400007278)

我该怎么做?


抱歉,您是要计算特殊列与单个列之间的皮尔逊相关系数还是特殊列与所有列名中的所有列之间的皮尔逊相关系数? - EdChum
@EdChum:special_col和每个中间的人。请查看我的更新的OP。 - neversaint
你需要使用corr函数。 - EdChum
自2019年以后,使用DataFrame.corrwith - william_grisaitis
如果我想计算special_col与colnames中所有列之间的Pearson相关系数怎么办? - codezero
4个回答

23

注意,您的数据中有一个错误,特殊列全部为3,因此无法计算相关性。

如果您在最后删除列选择,则会得到您正在分析的所有其他列的相关矩阵。 最后的 [:-1] 是为了消除“special_col”与自身的相关性。

In [15]: data[data.columns[1:]].corr()['special_col'][:-1]
Out[15]: 
stem1    0.500000
stem2   -0.500000
stem3   -0.999945
b1       0.500000
b2       0.500000
b3      -0.500000
Name: special_col, dtype: float64

如果你关心速度,这个在我的机器上稍微快一些:

In [33]: np.corrcoef(data[data.columns[1:]].T)[-1][:-1]
Out[33]: 
array([ 0.5       , -0.5       , -0.99994535,  0.5       ,  0.5       ,
       -0.5       ])

In [34]: %timeit np.corrcoef(data[data.columns[1:]].T)[-1][:-1]
1000 loops, best of 3: 437 µs per loop

In [35]: %timeit data[data.columns[1:]].corr()['special_col']
1000 loops, best of 3: 526 µs per loop

但显然,它返回的是一个数组,而不是pandas系列/数据框。


1
感谢您的快速响应时间! - Phlya

23

pd.DataFrame.corrwith() 可以替代 df.corr()

传入我们希望与其他列进行相关性计算的特定列。

对于上面的特定示例,代码将是: df.corrwith(df ['special_col'])

或者简单地使用 df.corr()['special_col'] 来创建每个列与其他列的完整相关性,并子集化您需要的内容。


12
你可以使用调用 corr 的 lambda 函数并传递 Series 'special_col' 来应用于你的列范围。
In [126]:
df[df.columns[1:-1]].apply(lambda x: x.corr(df['special_col']))

Out[126]:
stem1    0.500000
stem2   -0.500000
stem3   -0.999945
b1       0.500000
b2       0.500000
b3      -0.500000
dtype: float64

时间

实际上,另一种方法更快,因此我希望它能更好地扩展:

In [130]:
%timeit df[df.columns[1:-1]].apply(lambda x: x.corr(df['special_col']))
%timeit df[df.columns[1:]].corr()['special_col']

1000 loops, best of 3: 1.75 ms per loop
1000 loops, best of 3: 836 µs per loop

谢谢。有40K行和200多列。有没有办法可以加快速度? - neversaint
这将按列迭代。我不知道先在整个df上应用corr并选择“special_col”是否比仅按列对感兴趣的列执行更快。 - EdChum

7

为什么不直接这样做:

In [34]: df.corr().iloc[:-1,-1]
Out[34]:
stem1    0.500000
stem2   -0.500000
stem3   -0.999945
b1       0.500000
b2       0.500000
b3      -0.500000
Name: special_col, dtype: float64

或者:

In [39]: df.corr().ix['special_col', :-1]
Out[39]:
stem1    0.500000
stem2   -0.500000
stem3   -0.999945
b1       0.500000
b2       0.500000
b3      -0.500000
Name: special_col, dtype: float64

时序

In [35]: %timeit df.corr().iloc[-1,:-1]
1000 loops, best of 3: 576 us per loop

In [40]: %timeit df.corr().ix['special_col', :-1]
1000 loops, best of 3: 634 us per loop

In [36]: %timeit df[df.columns[1:]].corr()['special_col']
1000 loops, best of 3: 968 us per loop

In [37]: %timeit df[df.columns[1:-1]].apply(lambda x: x.corr(df['special_col']))
100 loops, best of 3: 2.12 ms per loop

我的机器上也更快了! - Phlya

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