2016-01-20 14 views
13

Ho un CSV che assomiglia a questo:Come fare correlazione di Pearson di colonne selezionate di un frame di dati Pandas

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 

E come frame di dati che appare così:

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 

Quello che ho voglio fare è eseguire la correlazione di Pearson dall'ultima colonna (special_col) con ogni colonna tra la colonna gene e special column, ovvero colnames[1:number_of_column-1]

Alla fine del giorno avremo una lunghezza di 6 frame dati.

Coln PearCorr 
stem1 0.5 
stem2 -0.5 
stem3 -0.9999453506011533 
b1 0.5 
b2 0.5 
b3 -0.5 

Il valore di cui sopra è calcolato manualmente:

In [27]: import scipy.stats 
In [39]: scipy.stats.pearsonr([3, 1, 3], [11,505,5]) 
Out[39]: (-0.9999453506011533, 0.0066556395400007278) 

Come posso fare questo?

+0

Spiacente stai chiedendo di calcolare la correlazione di Pearson tra special_col e una singola colonna o tra special_col e tutti i cols nei tuoi nomi? – EdChum

+0

@EdChum: special_col e tutti in mezzo. Vedi il mio OP aggiornato. – neversaint

+0

Stai cercando ['corr'] (http://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.DataFrame.corr.html) – EdChum

risposta

7

Nota: c'è un errore nei tuoi dati, là col particolare è tutto 3, quindi nessuna correlazione può essere calcolata.

Se si rimuove la selezione della colonna alla fine, si otterrà una matrice di correlazione di tutte le altre colonne che si stanno analizzando. L'ultimo [: -1] è quello di rimuovere la correlazione di 'special_col' con se stesso.

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 

Se siete interessati a velocità, questo è leggermente più veloce sulla mia macchina:

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 

Ma, ovviamente, restituisce un array, non una serie panda/DF.

+1

Questo è più veloce del mio metodo +1 – EdChum

+1

Grazie per i tempi rapidi! – Phlya

9

Puoi apply sul vostro intervallo di colonna con un lambda che chiama corr e passare i 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 

Tempi

In realtà l'altro metodo è più veloce quindi mi aspetto che in scala meglio :

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 
+0

Grazie. Ci sono 40K righe e 200+ colonne. C'è un modo per accelerarlo? – neversaint

+0

Questo itererà in termini di colonne Non so se applicare "corr" sull'intero df per primo e selezionare "special_col" sia più veloce di farlo solo sulle colonne di interesse per la colonna – EdChum

+1

Dovresti accettare l'altra risposta, è più veloce e mi aspetto che funzioni meglio sui tuoi dati reali – EdChum

6

Perché non basta fare:

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 

o:

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 

Tempi

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 
+0

Più veloce anche sulla mia macchina! – Phlya

Problemi correlati