在 numpy 中进入两个不同维度的数组时,点积和乘法矩阵是否相同
Are Dot product and Multiplying matrices are same when coming to arrays of two different dimensions in numpy
我在对两个向量进行点积时观察到一个奇怪的输出。我的代码是
a1 = np.array([[1], [2], [3]])
a2 = np.array([[1, 2, 3]])
print(a1*a2)
print(np.dot(a1, a2))
两者的输出相同,我不明白为什么在要求点时它会乘以两个矩阵
产品。对于 形状为 (x, 1) 和 (1, y) 的任何矩阵观察到相同的结果。
谢谢
在 numpy 中,dot
并不真正意味着点积。 dot
本质上表现得像矩阵乘法。因此,有人可能会争辩说它既多余又容易混淆,这就是我自己根本不使用它的原因。
要获得您似乎想要的行为,您可以改用 vdot
:
>>> np.vdot(a1,a2)
14
>>> np.vdot(a2,a1)
14
In [189]: a1 = np.array([[1], [2], [3]])
...: a2 = np.array([[1, 2, 3, 4]])
In [190]:
In [190]: a1.shape, a2.shape
Out[190]: ((3, 1), (1, 4))
矩阵乘法:
In [191]: a1@a2 # np.matmul
Out[191]:
array([[ 1, 2, 3, 4],
[ 2, 4, 6, 8],
[ 3, 6, 9, 12]])
广播元素乘法:
In [192]: a1*a2
Out[192]:
array([[ 1, 2, 3, 4],
[ 2, 4, 6, 8],
[ 3, 6, 9, 12]])
(3,1) 与 (1,4) => (3,4) 与 (3,4) => (3,4)
调整大小 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]])]
我在对两个向量进行点积时观察到一个奇怪的输出。我的代码是
a1 = np.array([[1], [2], [3]])
a2 = np.array([[1, 2, 3]])
print(a1*a2)
print(np.dot(a1, a2))
两者的输出相同,我不明白为什么在要求点时它会乘以两个矩阵
产品。对于 形状为 (x, 1) 和 (1, y) 的任何矩阵观察到相同的结果。
谢谢
在 numpy 中,dot
并不真正意味着点积。 dot
本质上表现得像矩阵乘法。因此,有人可能会争辩说它既多余又容易混淆,这就是我自己根本不使用它的原因。
要获得您似乎想要的行为,您可以改用 vdot
:
>>> np.vdot(a1,a2)
14
>>> np.vdot(a2,a1)
14
In [189]: a1 = np.array([[1], [2], [3]])
...: a2 = np.array([[1, 2, 3, 4]])
In [190]:
In [190]: a1.shape, a2.shape
Out[190]: ((3, 1), (1, 4))
矩阵乘法:
In [191]: a1@a2 # np.matmul
Out[191]:
array([[ 1, 2, 3, 4],
[ 2, 4, 6, 8],
[ 3, 6, 9, 12]])
广播元素乘法:
In [192]: a1*a2
Out[192]:
array([[ 1, 2, 3, 4],
[ 2, 4, 6, 8],
[ 3, 6, 9, 12]])
(3,1) 与 (1,4) => (3,4) 与 (3,4) => (3,4)
调整大小 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]])]