2016-01-20 6 views
6

Ich versuche, eine Funktion (Korrelation) auf allen paarweisen Kombinationen von Zeilen innerhalb eines Pandas Datenrahmen auszuführen:Python Pandas Funktion auf alle paarweise Kombinationen von Zeilen angewendet

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) 

Natürlich ist ziemlich langsam, und Ich frage mich, wie man das Äquivalent durch die Verwendung von etwas wie apply() oder anders machen kann.

Anmerkung: Ich weiß, dass ich direkt die Korrelation des Datenrahmen mit der pandas corr() Funktion finden kann, aber es nicht den zugehörigen p-Wert zurück (was ich für Filterzwecke benötigen)

+1

Wenn Sie in der Quelle aussehen [ 'pearsonr'] (https://github.com/scipy/scipy/blob/v0.16.1/scipy/stats/stats.py#L2514) finden Sie dass es nur ein paar Zeilen Code braucht, um den p-Wert zu berechnen, wenn Sie einen Korrelationskoeffizienten haben. Es sollte nicht sehr schwierig sein, eine 'Funktion' zu erstellen, die Sie mit' .apply (function) 'verwenden können. – Primer

+0

überlege, deinen Titel in etwas spezifischeres zu ändern :) –

Antwort

2

Dies sollen Ihnen einige bekommt beschleunigen. Definieren Sie eine Funktion Pearson, von der Dokumentation geändert in Primer der Link:

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) 

Verwenden applymap die elementweise Operationen auf dat.corr tut. Sie passieren die Korrelationskoeffizienten r zu 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) 

Sie mit dieser Methode Speedup sehen, wenn dat groß ist, aber es ist immer noch ziemlich langsam, weil die elementweise Operationen.

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 
Verwandte Themen