【问题标题】:Python pandas function applied to all pairwise combinations of rowsPython pandas 函数应用于所有成对的行组合
【发布时间】:2016-04-26 12:15:57
【问题描述】:

我正在尝试对 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() 函数的相关性,但它不会返回相关的 p 值(我需要它用于过滤目的)

【问题讨论】:

  • 如果你查看pearsonr的源码,你会发现如果你有相关系数,只需要几行代码就可以计算出p值。制作一个可以与.apply(function) 一起使用的function 应该不是很困难。
  • 考虑将您的标题更改为更具体的内容:)

标签: python pandas apply correlation


【解决方案1】:

这应该可以让您加快速度。定义一个函数Pearson,修改自 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)

使用applymapdat.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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-24
    • 2021-01-14
    • 2021-02-11
    相关资源
    最近更新 更多