【问题标题】:How to write this numpy code in vectorized form?如何以矢量化形式编写这个 numpy 代码?
【发布时间】:2015-12-08 14:25:07
【问题描述】:

我在 python 中有以下函数,我无法弄清楚如何以矢量化形式表达。 对我来说,cov 是一个形状为 (2,2) 的 numpy 数组,mu 是形状为 (2,) 的平均向量,xtp 是形状 (~50000,2)。 我知道 scipy 提供 scipy.stats.multivariate_normal.pdf 但我正在尝试学习如何编写高效的矢量化代码。请

def mvnpdf(xtp, mu, cov):
    temp = np.zeros(xtp.shape[0])
    i = 0
    length = xtp.shape[0]
    const = 1 / ( ((2* np.pi)**(len(mu)/2)) * (np.linalg.det(cov)**(1/2)) )
    inv = np.linalg.inv(cov)
    while i < length:
        x = xtp[i]-mu
        exponent = (-1/2) * (x.dot(inv).dot(x))
        temp[i] =  (const * np.exp(exponent))
        i+=1
    return temp

【问题讨论】:

    标签: python numpy scipy vectorization


    【解决方案1】:

    矢量化的唯一棘手部分是双 .dot。让我们隔离一下:

    x = xtp - mu  # move this out of the loop
    ddot = [i.dot(inv).dot(i) for i in x]
    temp = const * np.exp(-0.5 * ddot)
    

    把它放在你的代码中,看看它是否产生同样的东西。

    有几种“矢量化”dot 的方法。我喜欢先尝试的是einsum。在我的测试中这是等价的:

    ddot = np.einsum('ij,jk,ik->i',x,inv,x)
    

    我建议尝试一下它是否有效并加快速度。并在交互式 shell 中使用较小的数组(而不是 ~50000)进行这些计算。

    我正在测试

    In [225]: x
    Out[225]: 
    array([[  0.,   2.],
           [  1.,   3.],
           ...
           [  7.,   9.],
           [  8.,  10.],
           [  9.,  11.]])
    In [226]: inv
    Out[226]: 
    array([[ 1.,  0.],
           [ 0.,  1.]])
    

    由于这是一个学习练习,我将把细节留给你。

    使用(2,2),计算一个cov 可能比使用detinv 函数更快。但正是 length 迭代才是时间消耗者。

    【讨论】:

    猜你喜欢
    • 2013-01-05
    • 1970-01-01
    • 2017-06-22
    • 2018-03-15
    • 1970-01-01
    • 1970-01-01
    • 2021-01-10
    • 2021-07-08
    • 1970-01-01
    相关资源
    最近更新 更多