寻找以“正确”的方式在numpy中执行一系列矩阵向量乘积

时间:2018-07-17 19:00:43

标签: python arrays numpy

我有一个3D numpy数组vecsvecs的形状为[M,N,3]。也就是说,vecs是3元素向量的MxN集合。我正在寻找一种pythonic(numpythonic?)方法,以将每个向量的矩阵乘积与单个3x3矩阵mat一起使用。换句话说,我想要一种干净的方法来做到这一点:

>>>    for k in range(vecs.shape[0]):
>>>        for j in range(vecs.shape[1]):
>>>            vecs[k,j] = np.dot(mat, vecs[k,j])

有什么办法吗?

3 个答案:

答案 0 :(得分:3)

您的dot可以用einsum表示为:

res[k,j,:] = np.einsum('ab,b->a',mat,vecs[k,j,:])

并概括为与整个数组一起使用

res = np.einsum('ab,kjb->kja',mat,vecs)

答案 1 :(得分:2)

在这种情况下,我认为您可以做到

np.dot(vecs,mat.T)

下面是一小段代码,表明它们是相同的:

In [1]: import numpy as np

In [2]: a = np.random.randn(100,100,3)

In [3]: b = np.random.randn(3,3)

In [4]: expected = np.zeros_like(a)

In [5]: for i in range(a.shape[0]):
   ...:     for j in range(a.shape[1]):
   ...:         expected[i,j] = np.dot(b,a[i,j])
   ...:         

In [6]: np.allclose(expected,np.dot(a,b.T))
Out[6]: True

答案 2 :(得分:1)

您可以使用np.tensordot

vecs = np.tensordot(mat, vecs.T, axes=1).T

在这里,您将vecs换位以获得(3, M, N)数组,以便 将点积与mat一起应用,然后将所得的(3, N, M)转置为(M, N, 3)数组。

关于axes参数:

  

如果为int N,则将a的最后N个轴与b的前N个轴相加   为了。相应轴的尺寸必须匹配。

因此,在您的情况下,您沿着mat的第二轴与vecs.T的第一轴求和