Эффективно рассчитать коэффициент корреляции Пирсона только для одного столбца массива - PullRequest
1 голос
/ 04 мая 2020

У меня есть массив, имеющий форму ~ (700,36000), и я хотел бы рассчитать коэффициент корреляции Пирсона только для определенного столбца c (против всех других столбцов), но тысячи раз. Я пробовал это несколькими способами, но ни один из них не оказался настолько эффективным:

import numpy 

df_corr = numpy.corrcoef(df.T)
corr_column = df_corr.iloc[:, column_index]

Это, конечно, вычисляет всю матрицу корреляции и занимает ~ 12 с на моей машине; это проблема, так как мне нужно сделать это ~ 35 000 раз (arr слегка меняется каждый раз перед созданием корреляционной матрицы)!

Я также пытался выполнять итерации по столбцам по отдельности:

corr_column = numpy.zeros(len(df))

for x in df.columns:
    corr_column[x] = numpy.corrcoef(x=p_subset.iloc[:,gene_ix],y=p_subset.iloc[:,x])[0][1]
    corr_column = vals.reshape(-1,1)

Это немного быстрее, ~ 10 с за итерацию, но все еще слишком медленно. Есть ли способы быстрее найти коэффициент корреляции между столбцом и всеми другими столбцами?

1 Ответ

1 голос
/ 04 мая 2020

Ну, вы можете просто реализовать формулу самостоятельно:

import numpy as np

def corr(a, i):
    '''
    Parameters
    ----------
    a: numpy array
    i: column index

    Returns
    -------
    c: numpy array
       correlation coefficients of a[:,i] against all other columns of a
    '''

    mean_t = np.mean(a, axis=0)
    std_t = np.std(a, axis=0)

    mean_i = mean_t[i]
    std_i = std_t[i]

    mean_xy = np.mean(a*a[:,i][:,None], axis=0)

    c = (mean_xy - mean_i * mean_t)/(std_i * std_t)
    return c


a = np.random.randint(0,10, (700,36000))

%timeit corr(a,0)
608 ms ± 180 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit np.corrcoef(a.T)
# Actually didn't have the patience to let it finish in my machine 
# Using a smaller sample, the implementation above is 100x faster.
...