从 DataFrame 并行计算距离相关性 (dcor)

eod*_*eod 3 parallel-processing dataframe python-2.7 pandas

我有一个有 50 行和 22000 列的 Pandas DataFrame,我想计算每对列之间的距离相关性(dcor 包)。我创建的代码(带有串行处理和部分数据)是:

import pandas as pd
import dcor

DF = pd.DataFrame({'X':[0.72,-0.25,-1.2,-3],'Y':[-0.128,0.2,2,5.6],'Z':[15,-0.425,-0.3,-5]})

DCOR_REZ=pd.DataFrame(index=['X','Y','Z'],columns=['X','Y','Z'])
col_names=DCOR_REZ.columns.tolist()
k=0
for i in col_names:

    v1=DF.loc[:,i].as_matrix()
    for j in col_names[k:]:

        v2=DF.loc[:,j].as_matrix()
        rez=dcor.distance_correlation(v1,v2)
        DCOR_REZ.at[i,j]=rez
        DCOR_REZ.at[j,i]=rez

    k=k+1

print DCOR_REZ

         X        Y        Z
X        1 0.981778 0.854349
Y 0.981778        1 0.726328
Z 0.854349 0.726328        1
Run Code Online (Sandbox Code Playgroud)

要在完整的 DataFrame 上执行此代码,我需要 21 小时!.

由于我的服务器有40 个处理器,我想将时间减少 40 并在大约 30 分钟内获得结果,但我不知道如何重写此代码以进行并行处理

我怎样才能重写代码?

任何帮助表示赞赏。

Mab*_*bus 5

我是 dcor 包的创建者。这种方法的一个问题是每列的成对距离矩阵是在每次迭代中计算的,而不是一次。如果你有足够的内存,你可以预先计算这些矩阵,然后计算距离相关性:

import pandas as pd
import dcor
import numpy as np
from scipy.spatial.distance import pdist, squareform

DF = pd.DataFrame({'X':[0.72,-0.25,-1.2,-3],'Y':[-0.128,0.2,2,5.6],'Z':[15,-0.425,-0.3,-5]})

DCOR_REZ=pd.DataFrame(index=['X','Y','Z'],columns=['X','Y','Z'])
col_names=DCOR_REZ.columns.tolist()
k=0

dict_centered_matrices = {}

def compute_matrix(i):
    v1=DF.loc[:,i].as_matrix()

    v1_dist = squareform(pdist(v1[:, np.newaxis]))
    return (i, dcor.double_centered(v1_dist))

dict_centered_matrices = dict(map(compute_matrix, col_names))

for i in col_names:

    v1_centered = dict_centered_matrices[i]

    for j in col_names[k:]:

        v2_centered = dict_centered_matrices[j]

        rez=np.sqrt(
               dcor.average_product(v1_centered, v2_centered)/np.sqrt(
                                 dcor.average_product(v1_centered, v1_centered)*
                                 dcor.average_product(v2_centered, v2_centered)))

        DCOR_REZ.at[i,j]=rez
        DCOR_REZ.at[j,i]=rez

    k=k+1

print(DCOR_REZ)
Run Code Online (Sandbox Code Playgroud)

这应该会使您的代码更快,但会消耗更多内存。我会考虑为这种情况添加便利功能,因为它看起来很常见。您还可以尝试使用 multiprocessing 模块并行化代码,并将 map 函数替换为 Pool 实例的 map 方法。