Python - Numpy:3D矩阵* 2D矢量快速计算

时间:2016-05-07 21:52:42

标签: python arrays performance numpy matrix

大家好,

这是我想要做的。我有两个阵列:

  • rotation_matrices 包含50个二维旋转矩阵。每个旋转矩阵的形状为(2,2)。因此, rotation_matrices 的形状为(2,2,50)。
  • 向量包含50个二维向量。因此,它的形状为(2,50)。

我想要(如果存在)一行numpy操作,它给出了包含旋转向量的(2,50)数组,让我们称之为 rotating_vectors 。我的意思是 rotating_vectors 的第k个元素包含第k个旋转矩阵与第k个第i个向量的乘积。

目前,我已经提出了以下循环:

for ind,elt in enumerate(np.arange(nb_of_vectors)):
            rotated_vector[ind] = np.dot( rotation_matrices[:,:,ind], vectors[:,ind] )

我认为还有改进的余地。如果您有任何建议,欢迎您。

感谢您的时间。

Jagaral

3 个答案:

答案 0 :(得分:2)

对于需要沿一个或多个轴对齐的此类缩减,可以使用np.einsum -

rotated_vector = np.einsum('ijk,jk->ki',rotation_matrices,vectors)

请注意,输出的形状为(N,2),其中N是矢量数。相反,如果您希望输出形状(2,N)并且原始代码需要:rotated_vector[:,ind] = np.dot(...),则只需将输出字符串表示法编辑为ik而不是{ {1}}。

运行时测试 -

ki

再次证明为什么在NumPy迭代基本上只是坏

答案 1 :(得分:2)

您的轴处于异常状态。首先,您要将矩阵轴放在最后:

rotation_matrices = np.rollaxis(rotation_matrices, -1)  # shape (50, 2, 2)
vectors = np.rollaxis(vectors, -1)                      # shape (50, 2)

这将允许您使现有循环更具可读性:

for ind in np.arange(nb_of_vectors):
    rotated_vector[ind] = np.dot(rotation_matrices[ind], vectors[ind])

但相反,你可以使用矩阵乘法运算符(或python中的np.matmul< 3.5)

rotated_vectors = (a @ vectors[...,None])[...,0]
# rotated_vectors = np.matmul(a, vectors[...,None])[...,0]

[...,None]将向量数组(形状(n,))转换为列矩阵数组(形状(n, 1)),尾随[...,0]将列矩阵转换回载体

答案 2 :(得分:1)

这是一个明确的公式版本

result = np.array([vectors[0,:]*rotation_matrices[0,0,:] +
                   vectors[1,:]*rotation_matrices[0,1,:],
                   vectors[0,:]*rotation_matrices[1,0,:] +
                   vectors[1,:]*rotation_matrices[1,1,:]]).transpose()

比原始代码快很多(14x)但比我机器上的einsum慢(2.6x)

相关问题