我有一个3D numpy
数组vecs
。 vecs
的形状为[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])
有什么办法吗?
答案 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
的第一轴求和