【问题标题】:Calculating pairwise correlation among all columns计算所有列之间的成对相关性
【发布时间】:2023-03-27 23:34:01
【问题描述】:

我正在处理大型生物数据集。

我想计算我的数据表中所有 2 列组合的 PCC(Pearson 相关系数)并将结果保存为 DataFrame 或 CSV 文件。

数据表如下:columns是基因的名称,rows是dataset的代码。浮点数表示数据集中基因被激活的程度。

      GeneA GeneB GeneC ...
DataA 1.5 2.5 3.5 ...
DataB 5.5 6.5 7.5 ...
DataC 8.5 8.5 8.5 ...
...

作为输出,我想构建如下表(DataFrame 或 csv 文件),因为 scipy.stats.pearsonr 函数返回(PCC,p 值)。 在我的示例中,XX 和 YY 表示 pearsonr([1.5, 5.5, 8.5], [2.5, 6.5, 8.5]) 的结果。同理,ZZ 和 AA 表示 pearsonr([1.5, 5.5, 8.5], [3.5, 7.5, 8.5]) 的结果。我的测试中不需要 GeneB_GeneA 或 GeneC_GeneB 等冗余数据。

               PCC P-value
GeneA_GeneB    XX YY
GeneA_GeneC    ZZ AA
GeneB_GeneC    BB CC
...

由于列数和行数多(超过100),名称复杂,使用列名或行名会很困难。

这对于专家来说可能是一个简单的问题,我不知道如何用python和pandas库处理这种表。尤其是制作新的DataFrame并添加结果似乎非常困难。

对不起,我的解释很糟糕,但我希望有人能帮助我。

【问题讨论】:

  • 这里回答:link
  • 感谢您的评论。我认为标题不够好。我想知道的不是如何计算PCC,而是计算所有列对的PCC,并将结果保存为新的DataFrame。

标签: python pandas correlation


【解决方案1】:

要获得对,这是一个combinations 问题。您可以将concat 的所有行合并为一个结果dataframe

from pandas import *
from itertools import combinations
df = pandas.read_csv('gene.csv')
# get the column names as list, which are gene names
column_list = df.columns.values.tolist()
result = []
for c in combinations(column_list, 2):
    firstGene, secondGene = c
    firstGeneData = df[firstGene].tolist()
    secondGeneData = df[secondGene].tolist()
    # now to get the PCC, P-value using scipy
    pcc = ...
    p-value = ...
    result.append(pandas.DataFrame([{'PCC': pcc, 'P-value': p-value}], index=str(firstGene)+ '_' + str(secondGene), columns=['PCC', 'P-value'])

result_df = pandas.concat(result)
#result_df.to_csv(...)

【讨论】:

  • 我不知道“组合”,但是在进行这种配对计算时看起来不错。另外,我了解到可以通过 concat 函数轻松地从列表中制作 DataFrame。非常感谢!
【解决方案2】:
from pandas import *
import numpy as np
from libraries.settings import *
from scipy.stats.stats import pearsonr
import itertools

创建随机样本数据:

df = DataFrame(np.random.random((5, 5)), columns=['gene_' + chr(i + ord('a')) for i in range(5)]) 
print(df)

     gene_a    gene_b    gene_c    gene_d    gene_e
0  0.471257  0.854139  0.781204  0.678567  0.697993
1  0.292909  0.046159  0.250902  0.064004  0.307537
2  0.422265  0.646988  0.084983  0.822375  0.713397
3  0.113963  0.016122  0.227566  0.206324  0.792048
4  0.357331  0.980479  0.157124  0.560889  0.973161

correlations = {}
columns = df.columns.tolist()

for col_a, col_b in itertools.combinations(columns, 2):
    correlations[col_a + '__' + col_b] = pearsonr(df.loc[:, col_a], df.loc[:, col_b])

result = DataFrame.from_dict(correlations, orient='index')
result.columns = ['PCC', 'p-value']

print(result.sort_index())

                     PCC   p-value
gene_a__gene_b  0.461357  0.434142
gene_a__gene_c  0.177936  0.774646
gene_a__gene_d -0.854884  0.064896
gene_a__gene_e -0.155440  0.802887
gene_b__gene_c -0.575056  0.310455
gene_b__gene_d -0.097054  0.876621
gene_b__gene_e  0.061175  0.922159
gene_c__gene_d -0.633302  0.251381
gene_c__gene_e -0.771120  0.126836
gene_d__gene_e  0.531805  0.356315
  • 使用以下方法获取 DataFrame 列的唯一组合 itertools.combination(iterable, r)
  • 遍历这些组合并使用scipy.stats.stats.personr 计算成对相关性
  • 将结果(PCC 和 p 值元组)添加到 dictionary
  • dictionary 构建DataFrame

您还可以保存result.to_csv()。您可能会发现使用 MultiIndex(两列包含每列的名称)而不是为成对关联创建的名称更方便。

【讨论】:

  • 非常感谢!正如您和陈中普所建议的那样,使用组合功能似乎是解决此类问题的好方法。另外,我想再次感谢您的友好解释。这很有帮助,因为我是 python 新手。
  • 对不起,我的数据很大,所以很慢,我收到MemoryError: Unable to allocate 15.8 GiB for an array with shape (46063, 46063) and data type float64,有什么想法可以解决这个问题吗?
  • 上述解决方案精确地逐对计算相关性,以避免创建完整的相关性矩阵。
【解决方案3】:

一个简单的解决方案是使用Pingouin package(我创建的)的pairwise_corr函数:

import pingouin as pg
pg.pairwise_corr(data, method='pearson')

这将为您提供一个包含所有列组合的 DataFrame,以及每个列的 r 值、p 值、样本大小等。

还有许多选项可以指定一个或多个列(例如 one-vs-all 行为),以及用于偏相关的协变量和计算相关系数的不同方法。请参阅this example Jupyter Notebook 以获得更深入的演示。

【讨论】:

    【解决方案4】:

    假设您拥有的数据在 pandas DataFrame 中。

    df.corr('pearson')  # 'kendall', and 'spearman' are the other 2 options
    

    将为您提供每列之间的相关矩阵。

    【讨论】:

    • 抱歉,我收到了MemoryError: Unable to allocate 15.8 GiB for an array with shape (46063, 46063) and data type float64,有什么想法可以解决这个问题吗?谢谢。
    • 你真的需要检查46063列之间的相关性吗?如果没有,则创建一个新数据框,其中仅包含您要检查相关性的列。
    • 是的,我想看看是否可以这样做。
    • 您可以尝试将数据类型转换为 float32 或空间要求低于 float64 的类型。
    猜你喜欢
    • 1970-01-01
    • 2017-05-02
    • 2021-03-15
    • 2015-05-10
    • 1970-01-01
    • 2018-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多