Подтвердить что ты не робот

Как выполнить корреляцию Пирсона выбранных столбцов кадра данных Pandas

У меня есть 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

Я хочу сделать, чтобы выполнить корреляцию pearson из последнего столбца (special_col) с каждым столбцом между столбцом gene и special column, т.е. colnames[1:number_of_column-1]

В конце дня у нас будет длина кадра данных.

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)

Как я могу это сделать?

4b9b3361

Ответ 1

Обратите внимание, что в ваших данных есть ошибка, там специальный col - все 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 series/DF.

Ответ 2

Вы можете apply в своем диапазоне столбцов с lambda, который вызывает corr и передает 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

Ответ 3

Почему бы просто не сделать:

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