【问题标题】:Fast numpy covariance for arrays of different shape不同形状数组的快速 numpy 协方差
【发布时间】:2017-11-10 13:29:13
【问题描述】:

我需要获取形状为(M1, M2, N) 的数组a 和形状为(N,) 的另一个数组b 之间的协方差。

我目前做的是使用for 块:

import numpy as np

M1, M2, N = 23, 50, 117
a = np.random.uniform(-2., 2., (M1, M2, N))
b = np.random.uniform(-1., 1., N)

c = []
for i in range(M1):
    for j in range(M2):
        c.append(np.cov(a[i][j], b)[0, 1])

但是对于大的(M1, M2) 会有点慢。有没有办法加快速度?

【问题讨论】:

    标签: python arrays performance numpy covariance


    【解决方案1】:

    您始终可以手动计算 cov。以下是分别使用doteinsum 的两个建议。

    import numpy as np
    
    M1, M2, N = 23, 50, 117
    a = np.random.uniform(-2., 2., (M1, M2, N))
    b = np.random.uniform(-1., 1., N)
    
    c = []
    for i in range(M1):
        for j in range(M2):
            c.append(np.cov(a[i][j], b)[0, 1])
    
    c1 = np.reshape(c, (M1, M2))
    
    ac = a - a.mean(axis=-1, keepdims=True)
    bc = (b - b.mean()) / (N-1)
    
    c2 = np.dot(ac, bc)
    c3 = np.einsum('ijk,k->ij', ac, bc)
    print(np.allclose(c1, c2))
    print(np.allclose(c1, c3))
    

    打印

    True
    True
    

    【讨论】:

    • 很高兴见到你!折腾了一阵子,还是打不通。 tensordot 在张量上会比 dot 更好:np.tensordot(ac, bc, axes=((-1,-1))).
    • 所有三个选项(np.einsumnp.dotnp.tensordot)都比 for 块快很多。因为显然它们都同样快,所以我会选择np.dot,这(对我来说)更容易解释。谢谢你们!
    猜你喜欢
    • 2016-05-14
    • 1970-01-01
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    • 2019-01-20
    • 1970-01-01
    • 2017-03-16
    • 1970-01-01
    相关资源
    最近更新 更多