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_loops
и using_einsum
тот же результат.
In [260]: np.allclose(using_loops(U, K), using_einsum(U, K))
Out[260]: True
Это показывает using_einsum быстрее; насколько быстрее, зависит от размера n
и k
:
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-loops.
'for j in xrange (n) и j! = I' должно было повысить значение SyntaxError. Вы хотели разбить это на 'for-loop' и' if-statement'? – unutbu
@unutbu да, вы правы, я хочу сказать: 'for j in xrange (n): if j! = I:' но я ошибся в синтаксисе, и мне интересно, есть ли лучший способ сделать это ~ – AnnabellChan