Vectorise顺序numpy计算

时间:2017-07-10 02:45:13

标签: python performance numpy

我在numpy中有很多操作,我可以在一个循环中完美地执行,但我还没有能够在一个不正常的调用中对它们进行矢量化。

# data matrix
d = np.random.rand(1496, 1, 2)

# boolean matrix
r = np.random.rand(5, 1496, 1, 2) > 0.5

# result matrix
x = np.empty((5,))

# How can I avoid this loop?
for i in xrange(r.shape[0]):
  x[i] = d[r[i]].sum()

是否可以通过某种方式对循环进行矢量化来加快速度?

2 个答案:

答案 0 :(得分:2)

@Psidom方法的变体:

np.tensordot(d, r, axes=((0,1,2), (1,2,3)))

这取决于tensordot功能。来自documentation

  

给定两个张量(维度大于或等于1的数组),ab,以及包含两个array_like对象(a_axes, b_axes)的array_like对象,求和的乘积{由ab指定的轴上的{1}}和a_axes个元素(组件)。

从根本上说,b_axes计算两个数组的乘积(就像@Psidom一样),并计算产品数组的所有元素的总和。与@ Psidom的方法相比,这种方法的唯一“优势”在于,它允许更灵活地指定哪些轴在两个数组中执行产品和求和 。与@ Psidom的方法相比,它没有提供更好的性能。

另请参阅Understanding tensordot

答案 1 :(得分:1)

您可以将其矢量化为此;由于d是一个小于r的维度,当它们相乘时,d将在axis=0的{​​{1}}广播,因此避免循环;此外,由于r是一个布尔数组,r将与d[r].sum()相同:

(d*r).sum

结果与(d * r).sum(axis=(1,2,3)) # array([ 775.17049697, 728.61537246, 735.05686655, 765.19469927, # 759.44834287]) 相同:

x