2016-01-20 49 views
6

我想一個大熊貓數據幀中運行行的所有配對組合功能(相關性):Python的大熊貓功能應用於行的所有配對組合

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) 

當然,這是相當緩慢的,我想知道如何通過使用類似apply()或其他方式來實現相同效果。

注:我知道我可以直接找到與pandas corr()功能數據幀的相關性,但它不返回相關的p值(我需要過濾的目的)

+1

如果你的源看['pearsonr'(https://github.com/scipy/scipy/blob/v0.16.1/scipy/stats/stats.py#L2514),你會發現如果你有相關係數,只需要幾行代碼來計算p值。製作一個''''應用程序(函數)'可以使用''應該不是很困難。 – Primer

+0

考慮改變你的標題爲更具體的東西:) –

回答

2

這應該給你一些加速。定義一個函數Pearson,在底漆的鏈接從文檔修改:

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) 

使用applymap這確實對dat.corr元素方面的操作。要傳遞的相關係數rPearson

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) 

你看到使用這種方法的加速比當dat很大,但它是因爲元素方面的操作仍相當緩慢。

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