繁星淼淼
In [189]: a1 = np.array([[1], [2], [3]]) ...: a2 = np.array([[1, 2, 3, 4]])In [190]: In [190]: a1.shape, a2.shapeOut[190]: ((3, 1), (1, 4))矩阵乘法:In [191]: a1@a2 # np.matmulOut[191]: array([[ 1, 2, 3, 4], [ 2, 4, 6, 8], [ 3, 6, 9, 12]])广播元素乘法:In [192]: a1*a2Out[192]: array([[ 1, 2, 3, 4], [ 2, 4, 6, 8], [ 3, 6, 9, 12]])(3,1) 与 (1,4) => (3,4) 与 (3,4) => (3,4)调整 Size 1 维度以匹配其他数组与matmul:In [193]: a1.dot(a2)Out[193]: array([[ 1, 2, 3, 4], [ 2, 4, 6, 8], [ 3, 6, 9, 12]])形状不匹配:In [194]: a2.dot(a1)Traceback (most recent call last): File "<ipython-input-194-4e2276e15f5f>", line 1, in <module> a2.dot(a1)ValueError: shapes (1,4) and (3,1) not aligned: 4 (dim 1) != 3 (dim 0)用爱因斯坦符号:In [195]: np.einsum('ij,jk->ik',a1,a2)Out[195]: array([[ 1, 2, 3, 4], [ 2, 4, 6, 8], [ 3, 6, 9, 12]])在真正的矩阵乘法中,这会将所有行乘以所有列,并在共享维度上求和。因为j维度为 1,所以求和没有什么区别。我们可以看到广播的效果:In [198]: np.broadcast_arrays(a1,a2)Out[198]: [array([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]]), array([[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]])]