如何计算Pandas中列的成对相关的p值?

n10*_*000 2 python correlation dataframe pandas

Pandas具有非常方便的功能,可以使用pd.corr()对列进行成对关联。这意味着可以比较任何长度的列之间的相关性。例如:

df = pd.DataFrame(np.random.randint(0,100,size=(100, 10)))

     0   1   2   3   4   5   6   7   8   9
0    9  17  55  32   7  97  61  47  48  46
1    8  83  87  56  17  96  81   8  87   0
2   60  29   8  68  56  63  81   5  24  52
3   42  76   6  75   7  59  19  17   3  63
...
Run Code Online (Sandbox Code Playgroud)

现在可以使用以下命令测试所有10列之间的相关性df.corr(method='pearson')

      0         1         2         3         4         5         6         7         8         9
0  1.000000  0.082789 -0.094096 -0.086091  0.163091  0.013210  0.167204 -0.002514  0.097481  0.091020
1  0.082789  1.000000  0.027158 -0.080073  0.056364 -0.050978 -0.018428 -0.014099 -0.135125 -0.043797
2 -0.094096  0.027158  1.000000 -0.102975  0.101597 -0.036270  0.202929  0.085181  0.093723 -0.055824
3 -0.086091 -0.080073 -0.102975  1.000000 -0.149465  0.033130 -0.020929  0.183301 -0.003853 -0.062889
4  0.163091  0.056364  0.101597 -0.149465  1.000000 -0.007567 -0.017212 -0.086300  0.177247 -0.008612
5  0.013210 -0.050978 -0.036270  0.033130 -0.007567  1.000000 -0.080148 -0.080915 -0.004612  0.243713
6  0.167204 -0.018428  0.202929 -0.020929 -0.017212 -0.080148  1.000000  0.135348  0.070330  0.008170
7 -0.002514 -0.014099  0.085181  0.183301 -0.086300 -0.080915  0.135348  1.000000 -0.114413 -0.111642
8  0.097481 -0.135125  0.093723 -0.003853  0.177247 -0.004612  0.070330 -0.114413  1.000000 -0.153564
9  0.091020 -0.043797 -0.055824 -0.062889 -0.008612  0.243713  0.008170 -0.111642 -0.153564  1.000000
Run Code Online (Sandbox Code Playgroud)

是否有一种简单的方法也可以获取相应的p值(理想情况下是熊猫),因为它是由scipy的kendalltau()返回的?

ALo*_*llz 6

可能只是循环。无论如何,这基本上是pandas在源代码中所做的生成相关矩阵的工作:

import pandas as pd
import numpy as np
from scipy import stats

df_corr = pd.DataFrame() # Correlation matrix
df_p = pd.DataFrame()  # Matrix of p-values
for x in df.columns:
    for y in df.columns:
        corr = stats.pearsonr(df[x], df[y])
        df_corr.loc[x,y] = corr[0]
        df_p.loc[x,y] = corr[1]
Run Code Online (Sandbox Code Playgroud)

如果你想利用这是对称的事实,所以你只需要计算大约一半的这个,然后做:

mat = df.values.T
K = len(df.columns)
correl = np.empty((K,K), dtype=float)
p_vals = np.empty((K,K), dtype=float)

for i, ac in enumerate(mat):
    for j, bc in enumerate(mat):
        if i > j:
            continue
        else:
            corr = stats.pearsonr(ac, bc)
            #corr = stats.kendalltau(ac, bc)

        correl[i,j] = corr[0]
        correl[j,i] = corr[0]
        p_vals[i,j] = corr[1]
        p_vals[j,i] = corr[1]

df_p = pd.DataFrame(p_vals)
df_corr = pd.DataFrame(correl)
#pd.concat([df_corr, df_p], keys=['corr', 'p_val'])
Run Code Online (Sandbox Code Playgroud)


Ram*_*mau 6

为什么不使用pandas.DataFrame.corr()的“ method”参数:

  • 皮尔逊:标准相关系数
  • kendall:Kendall Tau相关系数
  • Spearman:Spearman等级相关
  • 可调用:可调用,输入两个1d ndarrays并从中返回浮点数

scipy.stats import kendalltau, pearsonr, spearmanr

def kendall_pval(x,y):
    return kendalltau(x,y)[1]

def pearsonr_pval(x,y):
    return pearsonr(x,y)[1]

def spearmanr_pval(x,y):
    return spearmanr(x,y)[1]
Run Code Online (Sandbox Code Playgroud)

然后

corr = df.corr(method=pearsonr_pval)
Run Code Online (Sandbox Code Playgroud)

  • df.corr(method='pearson') 计算*相关系数*,而 df.corr(method=pearsonr_pval) 计算*p-value*,这是不同的东西。如果你定义: def pearson_corr(x,y): return pearsonr(x,y)[0],那么 df.corr(method='pearson') 应该给出与 df.corr(method=pearson_corr) 相同的输出:) (2认同)
  • 最佳答案 IMO,唯一值得留下的注释是你需要 pandas >= 0.24 。奇迹般有效! (2认同)