【问题标题】:How to efficiently sum numpy arrays after multiply them?将它们相乘后如何有效地求和numpy数组?
【发布时间】:2015-01-22 22:30:15
【问题描述】:

其实我需要计算:

S_i = sum(U_j * U_j.transpose) * K_i

在哪里

U_j is a n * k dim matrix, 
K_i is a n * n dim matrix, 
j != i, 
i = 1, 2, ..., n

我使用了这样的循环:

import numpy as np
for i in xrange(n):
    temp = np.zeros((n, n))
    for j in xrange (n):
        if j != i:
            temp += np.dot(U[j], U[j].T)
    S[i] = np.dot(temp, K[i])

有没有更有效的方法来做到这一点?

【问题讨论】:

  • for j in xrange (n) and j != i 应该引发了 SyntaxError。您的意思是将其分解为for-loopif-statement
  • @unutbu 是的,你是对的,我的意思是 for j in xrange(n): if j != i: 但我在语法上犯了一个错误,我想知道有没有更好的方法来做到这一点~

标签: arrays for-loop numpy add multiplication


【解决方案1】:
import numpy as np

n, k = 30, 40

U = np.random.random((n, n, k))
K = np.random.random((n, n, n))

def using_loops(U, K):
    S = np.empty((n, n, n))
    for i in xrange(n):
        temp = np.zeros((n, n))
        for j in xrange (n):
            if j != i:
                temp += np.dot(U[j], U[j].T)
        S[i] = np.dot(temp, K[i])
    return S

def using_einsum(U, K):
    uut = np.einsum('ijk,ilk->ijl', U, U)
    total = uut.sum(axis=0)
    total = total - uut
    S = np.einsum('ijk,ikl->ijl', total, K)
    return S

这测试using_loopsusing_einsum 产生相同的结果。

In [260]: np.allclose(using_loops(U, K), using_einsum(U, K))
Out[260]: True

这表明 using_einsum 更快;快多少取决于nk的大小:

In [262]: %timeit using_loops(U, K)
100 loops, best of 3: 17.1 ms per loop

In [263]: %timeit using_einsum(U, K)
1000 loops, best of 3: 1.92 ms per loop

一般来说,每当您看到产品的总和时,很有可能 np.einsum 将是产生结果的相当快的方法。它几乎肯定会击败 Python for 循环。

【讨论】:

  • 我已经阅读了“np.einsum”的使用文档,但我对参数“操作数”感到很困惑。最后一个例子是np.einsum('ki,jk->ij', a, b),如果我没记错的话,我认为它等于np.dot(a.T, b.T)。但是为什么操作数是 ki, jk->ij 而不是 ji, kj->ik 呢?要是你能给我解释一下就好了~thx~~
  • 如果公式S_i = sum(U_j * U_j.transpose) * K_i其中i不一定等于n但远小于n,有什么变化吗关于使用np.dotnp.einsum的时间效率差异?
  • 关于numpy.einsum中的操作数,我想通了~谢谢~:)
  • 我很高兴你在np.einsum 中找到了下标符号——这需要一些时间来适应。对于第二个问题,你的意思是你只希望计算S_i 的几个值(或单个值)i 远小于n
  • 对,就是这个意思~在这种情况下,使用np.dotnp.einsum的效率怎么样~?
猜你喜欢
  • 1970-01-01
  • 2017-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-28
  • 2020-09-23
相关资源
最近更新 更多