Python pandas 函数应用于所有行的成对组合
Python pandas function applied to all pairwise combinations of rows
我正在尝试 运行 pandas 数据帧中所有成对行组合的函数(相关性):
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() 函数的相关性,但它不会 return 关联的 p 值(我需要用于过滤目的)
这应该可以加快您的速度。定义一个函数 Pearson
,修改自 Primer 的 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)
使用 applymap
对 dat.corr
进行逐元素运算。您正在将相关系数 r
传递给 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)
当 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
我正在尝试 运行 pandas 数据帧中所有成对行组合的函数(相关性):
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() 函数的相关性,但它不会 return 关联的 p 值(我需要用于过滤目的)
这应该可以加快您的速度。定义一个函数 Pearson
,修改自 Primer 的 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)
使用 applymap
对 dat.corr
进行逐元素运算。您正在将相关系数 r
传递给 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)
当 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