2016-01-20 22 views
6

sto cercando di eseguire una funzione (correlazione) su tutte le combinazioni coppie di righe di un dataframe panda:funzione panda Python applicato a tutte le combinazioni a coppie delle righe

stats = dict() 
for l in itertools.combinations(dat.index.tolist(),2): 
    stats[l] = pearsonr(dat.loc[l[0],:], dat.loc[l[1],:]) # stores (r, p) 

Naturalmente questo è piuttosto lento, e Mi chiedo come fare l'equivalente attraverso l'uso di qualcosa come apply() o in altro modo.

Nota: So che posso trovare direttamente la correlazione del dataframe con la funzione pandas corr(), tuttavia non restituisce il p-value associato (che mi serve per scopi di filtraggio)

+1

Se si guarda la fonte di [ 'pearsonr'] (https://github.com/scipy/scipy/blob/v0.16.1/scipy/stats/stats.py#L2514) troverete che ci vogliono solo poche righe di codice per calcolare il valore p se si dispone di coefficiente di correlazione. Non dovrebbe essere molto difficile creare una 'funzione' che tu possa usare con' .apply (function) '. – Primer

+0

considera la possibilità di cambiare il titolo in qualcosa di più specifico :) –

risposta

2

Questo dovrebbe farti un po ' accelerare. Definire una funzione Pearson, modificata dalla documentazione in collegamento di Primer:

def Pearson(r, n=len(dat)): 
    r = max(min(r, 1.0), -1.0) 
    df = n - 2 
    if abs(r) == 1.0: 
     prob = 0.0 
    else: 
     t_squared = r**2 * (df/((1.0 - r) * (1.0 + r))) 
     prob = betai(0.5*df, 0.5, df/(df+t_squared)) 

    return (r,prob) 

Usa applymap che fa operazioni elemento-saggio su dat.corr. Si passa il coefficiente di correlazione r a Pearson:

np.random.seed(10) 
dat = pd.DataFrame(np.random.randn(5, 5)) 
dat[0] = np.arange(5) # seed two correlated cols 
dat[1] = np.arange(5) # ^^^ 

dat.corr().applymap(Pearson) 

    0 1 2 3 4 
0 (1.0, 0.0) (1.0, 0.0) (0.713010395675, 0.176397305541) (0.971681374885, 0.00569624513678) (0.0188249871501, 0.97603269768) 
1 (1.0, 0.0) (1.0, 0.0) (0.713010395675, 0.176397305541) (0.971681374885, 0.00569624513678) (0.0188249871501, 0.97603269768) 
2 (0.713010395675, 0.176397305541) (0.713010395675, 0.176397305541) (1.0, 0.0) (0.549623945218, 0.337230071385) (-0.280514871109, 0.647578381153) 
3 (0.971681374885, 0.00569624513678) (0.971681374885, 0.00569624513678) (0.549623945218, 0.337230071385) (1.0, 0.0) (0.176622737448, 0.77629170593) 
4 (0.0188249871501, 0.97603269768) (0.0188249871501, 0.97603269768) (-0.280514871109, 0.647578381153) (0.176622737448, 0.77629170593)  (1.0, 0.0) 

Non vedi velocizzare con questo metodo quando dat è grande, ma è ancora piuttosto lento a causa delle operazioni di elementi-saggio.

np.random.seed(10) 
dat = pd.DataFrame(np.random.randn(100, 100)) 

%%timeit 
dat.corr().applymap(Pearson) 

10 loops, best of 3: 118 ms per loop 

%%timeit 
stats = dict() 

for l in combinations(dat.index.tolist(),2): 
    stats[l] = pearsonr(dat.loc[l[0],:], dat.loc[l[1],:]) 

1 loops, best of 3: 1.56 s per loop