【发布时间】:2012-07-01 04:54:03
【问题描述】:
我能否消除此计算中的所有 Python 循环:
result[i,j,k] = (x[i] * y[j] * z[k]).sum()
其中x[i]、y[j]、z[k] 是长度为N 和x、y、z 的向量具有长度为A、B、@9876543 的第一个维度英石输出是形状(A,B,C),每个元素都是
三重乘积的总和(按元素)。
我可以将它从 3 个循环减少到 1 个循环(下面的代码),但我一直在尝试 消除最后一个循环。
如有必要,我可以制作A=B=C(通过少量填充)。
# 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)
【问题讨论】:
-
很遗憾,这不是作业问题。实际上,如果有关于“我如何矢量化”这一一般主题的课程/教科书,我会很高兴!
标签: python numpy linear-algebra vectorization