a=np.arange(18).reshape(2,3,3)
b=np.arange(6).reshape(2,3)
我想计算点积
a[0]@b[0]
array([ 5, 14, 23])
a[1]@b[1]
array([122, 158, 194])
通过广播,我试过了
c=a@b[...,None]
c
array([[[ 5],
[ 14],
[ 23]],
[[122],
[158],
[194]]])
但形状不是我想要的
c.shape
(2, 3, 1)
除了更改轴的方式外,如何在计算中得到形状(2, 3)
而不是(2, 3, 1)
?
对于广播,为什么[:,None]
不起作用? ...
在这里意味着什么?
答案 0 :(得分:2)
在这种情况下,b[...,None]
与b[:,:,None]
,(2,3,1)数组相同。 ...
表示'尽可能多:
'。
因此,点积和是3
的{{1}}和a
的中间3
(第二个到最后一个)。
您可以使用b
删除1号尺寸。
但是对于(2,3,3)和(2,3),您想要哪squeeze
个产品?在dot
表示法中,我可以看到
einsum
具有2个2d阵列的 'ijk,ij->ik'
'ijk,ik->ij'
'ijk,mj->imk'
etc
产品定义明确。但是当一个人是3d时,就会产生一些歧义。
dot
来自In [2]: a=np.arange(18).reshape(2,3,3)
...: b=np.arange(6).reshape(2,3)
...:
In [3]: np.einsum('ijk,ik->ij',a,b)
Out[3]:
array([[ 5, 14, 23],
[122, 158, 194]])
In [4]: np.dot(a,b)
ValueError: shapes (2,3,3) and (2,3) not aligned: 3 (dim 2) != 2 (dim 0)
In [6]: np.dot(a,b[:,:,None]).shape # 'ijk,kml->ijml'
Out[6]: (2, 3, 2, 1)
In [7]: np.matmul(a,b[:,:,None]).shape # @
Out[7]: (2, 3, 1)
In [8]: np.einsum('ijk,ikm->ijm',a,b[...,None])
Out[8]:
array([[[ 5],
[ 14],
[ 23]],
[[122],
[158],
[194]]])
In [12]: np.squeeze(_) # removing that added dimension
Out[12]:
array([[ 5, 14, 23],
[122, 158, 194]])
文档的相关说明是:
如果任一参数是N-D,则N> 2,它被视为一堆 驻留在最后两个索引中的矩阵并相应地进行广播。
ValueError - 如果
matmul
的最后一个维度与大小不同a
的倒数第二维。
b
中广播的一个例子是:
matmul
我刚刚了解到In [15]: a@b.T
Out[15]:
array([[[ 5, 14],
[ 14, 50],
[ 23, 86]],
[[ 32, 122],
[ 41, 158],
[ 50, 194]]])
In [16]: _.shape
Out[16]: (2, 3, 2)
In [17]: a@b.T[None,:,:]
Out[17]:
array([[[ 5, 14],
[ 14, 50],
[ 23, 86]],
[[ 32, 122],
[ 41, 158],
[ 50, 194]]])
现在是optimize=True
的默认值,而且这并不总是最快。
einsum