Python numpy 3D点积

Python numpy 3D点积,python,numpy,vectorization,dot-product,array-broadcasting,Python,Numpy,Vectorization,Dot Product,Array Broadcasting,我有两个3dim numpy矩阵,我想根据一个轴做点积,而不使用循环: a=[ [[ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0], [ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], [ 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1], [ 0, 1, 0, 0, 0,

我有两个3dim numpy矩阵,我想根据一个轴做点积,而不使用循环:

a=[ [[ 0, 0, 1, 1, 0,  0,  0,  0,  0,  0,  1,  0,  0,  1,  0],
  [ 1,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0],
  [ 0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  1],
  [ 0,  1,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  1,  0,  0]],
    [[ 0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  1,  0,  0,  1,  0],
  [ 1,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0],
  [ 0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  1],
  [ 0,  1,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  1,  0,  0]],
 [ [ 0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  1,  0,  0,  1,  0],
  [ 1,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0],
  [ 0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  1],
  [ 0,  1,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  1,  0,  0]],
 [ [ 0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  1,  0,  0,  1,  0],
  [ 1,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0],
  [ 0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  1],
  [ 0,  1,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  1,  0,  0]],
 [[ 0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  1,  0,  0,  1,  0],
  [ 1,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0],
  [ 0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  1],
  [ 0,  1,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  1,  0,  0]],
 [[ 0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  1,  0,  0,  1,  0],
  [ 1,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0],
  [ 0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  1],
  [ 0,  1,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  1,  0,  0.]],
 [[ 0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  1,  0,  0,  1,  0],
  [ 1,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0],
  [ 0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  1],
  [ 0,  1,  0,  0,  0,  0,  1,  0,  0,  0,  1,  0,  1,  0,  0]]]

b=[[[ 0,  0,  1,  0,  0.],
  [ 1,  0,  0,  0,  0.],
  [ 0,  0,  0,  0,  0.],
  [ 0,  1,  0,  0,  0.]],
 [[ 0,  0,  1,  0,  0.],
  [ 1,  0,  0,  0,  0.],
  [ 0,  0,  0,  0,  0.],
  [ 0,  1,  0,  0,  0.]],
 [[ 0,  0,  1,  0,  0.],
  [ 1,  0,  0,  0,  0.],
  [ 0,  0,  0,  0,  0.],
  [ 0,  1,  0,  0,  0.]],
 [[ 0,  0,  1,  0,  0.],
  [ 1,  0,  0,  0,  0.],
  [ 0,  0,  0,  0,  0.],
  [ 0,  1,  0,  0,  0.]],
 [[ 0,  0,  1,  0,  0.],
  [ 1,  0,  0,  0,  0.],
  [ 0,  0,  0,  0,  0.],
  [ 0,  1,  0,  0,  0.]],
 [[ 0,  0,  1,  0,  0.],
  [ 1,  0,  0,  0,  0.],
  [ 0,  0,  0,  0,  0.],
  [ 0,  1,  0,  0,  0.]],
 [[ 0,  0,  1,  0,  0.],
  [ 1,  0,  0,  0,  0.],
  [ 0,  0,  0,  0,  0.],
  [ 0,  1,  0,  0,  0.]]]
dt = np.dtype(np.float32)
a=np.asarray(a,dtype=dt)
b=np.asarray(b,dtype=dt)
print(a.shape)
print(b.shape)
a的形状是7,4,15,b的形状是7,4,5。 我希望c=np.dota,b的大小为7,5,15,如下所示:

c = np.zeros((7,15,5))
for i in range(7):
   c[i,:,:] = np.dot(a[i,:,:].T , b[i,:,:])
但是我正在寻找一个没有for循环的解决方案。比如:

c = np.tensordot(a.reshape(4,7,5),b.reshape(7,4,15),axes=([1,0],[0,1]))
但这一个并不像预期的那样有效

我也试过:

newaxes_a=[2,0,1]
newaxes_b=[1,0,2]

newshape_a=(-1,28)
newshape_b=(28,-1)
a_t = a.transpose(newaxes_a).reshape(newshape_a)
b_t = b.transpose(newaxes_b).reshape(newshape_b)
c = np.dot(a_t, b_t)
这并没有像预期的那样起作用

有什么想法吗?

你可以用-

另一个使用-

你可以用-

另一个使用-


哦太好了theano中是否也有等效函数?我还需要在theano中实现它。@Anxam在theano上广播怎么样?请查看基于此的解决方案。此处提供了一个解决方案:但我不确定它是否适用于我。@Anxam的条件略有不同,因为您在这里切割一个暗度并保持一个暗度。在相关的问题中,它只涉及削减一个维度。所以,如果你要在这里复制同样的行为,你需要重塑和转换。这将是一个混乱的解决方案。我明白了……如果我使用类似于einsum的计算的索引生成一个矩阵,并使用这些索引构建一个更大的矩阵来输入到我的theano函数中,会怎么样?我不太确定它将如何工作,但也许最好是在两个矩阵上工作,通过应用theano.dot得到我想要的结果。哦。。。太好了theano中是否也有等效函数?我还需要在theano中实现它。@Anxam在theano上广播怎么样?请查看基于此的解决方案。此处提供了一个解决方案:但我不确定它是否适用于我。@Anxam的条件略有不同,因为您在这里切割一个暗度并保持一个暗度。在相关的问题中,它只涉及削减一个维度。所以,如果你要在这里复制同样的行为,你需要重塑和转换。这将是一个混乱的解决方案。我明白了……如果我使用类似于einsum的计算的索引生成一个矩阵,并使用这些索引构建一个更大的矩阵来输入到我的theano函数中,会怎么样?我不太确定它将如何工作,但也许最好是在两个矩阵上工作,通过应用theano.dot得到我想要的结果。for循环有什么问题?如果您使用优化的BLAS运行numpy,那么它就是目前发布的最快版本。@Ophion实际上,我正在寻找一个基于Theano的解决方案。我在发布的另一个相关问题中回复了您的评论。for循环有什么问题?如果您使用优化的BLAS运行numpy,那么它就是目前发布的最快版本。@Ophion实际上,我正在寻找一个基于Theano的解决方案。我在我发布的其他相关问题中回复了你的评论。
#to match the given example
c2 = np.einsum('ijk,ijl->ikl',a,b)
print np.allclose(c, c2)
c = (a[:,:,None,:]*b[...,None]).sum(1)