私はこの計算では、すべてのPythonのループを排除することができる:x[i]
は、y[j]
は、z[k]
は長N
とx
、y
のベクトルでnumpyで2次元配列上のこのトリプルループをベクトル化するにはどうすればよいですか?
result[i,j,k] = (x[i] * y[j] * z[k]).sum()
は、z
は長A
、B
有する第一の寸法を有し、C
S。T.出力は形状(A,B,C)
であり、各要素は で、3つの積の合計(要素ごと)です。
私は3から1ループ(下のコード)からダウンすることができますが、最後のループを解消するために を試みました。
A=B=C
(必要な場合は少量のパディング)。あなたのループのバージョンと同じです
np.einsum('im,jm,km->ijk',x,y,z)
:
# Example with 3 loops, 2 loops, 1 loop (testing omitted)
N = 100 # more like 100k in real problem
A = 2 # more like 20 in real problem
B = 3 # more like 20 in real problem
C = 4 # more like 20 in real problem
import numpy
x = numpy.random.rand(A, N)
y = numpy.random.rand(B, N)
z = numpy.random.rand(C, N)
# outputs of each variant
result_slow = numpy.empty((A,B,C))
result_vec_C = numpy.empty((A,B,C))
result_vec_CB = numpy.empty((A,B,C))
# 3 nested loops
for i in range(A):
for j in range(B):
for k in range(C):
result_slow[i,j,k] = (x[i] * y[j] * z[k]).sum()
# vectorize loop over C (2 nested loops)
for i in range(A):
for j in range(B):
result_vec_C[i,j,:] = (x[i] * y[j] * z).sum(axis=1)
# vectorize one C and B (one loop)
for i in range(A):
result_vec_CB[i,:,:] = numpy.dot(x[i] * y, z.transpose())
numpy.testing.assert_almost_equal(result_slow, result_vec_C)
numpy.testing.assert_almost_equal(result_slow, result_vec_CB)
この宿題はありますか? – Dhara
悲しいことに、それは宿題の問題ではありません。実際には、「私はどのようにベクトル化するのか」という一般的な話題のコースや教科書があれば、私はとても嬉しく思っています! –