为什么Python/Numpy要求使用行向量进行矩阵/向量点积运算?

6
假设我们想要计算矩阵和列向量的点积:

Matrix dot vector

因此,在Numpy/Python中,我们开始:

a=numpy.asarray([[1,2,3], [4,5,6], [7,8,9]])
b=numpy.asarray([[2],[1],[3]])
a.dot(b)

结果如下:

array([[13], [31], [49]])

到目前为止,一切都很好,但是为什么这也有效呢?

b=numpy.asarray([2,1,3])
a.dot(b)

结果为:

array([13, 31, 49])

我本来期望[2,1,3]是一个行向量(需要转置才能进行点积运算),但Numpy似乎默认将数组视为列向量(在矩阵乘法的情况下)?

这是如何工作的?

编辑:

为什么是:

b=numpy.asarray([2,1,3])
b.transpose()==b

所以矩阵点乘向量数组确实有效(因此将其视为列向量),但其他操作(转置)无法正常工作。这不是一致的设计,不是吗?

相关问题:https://dev59.com/k2Qm5IYBdhLWcg3wrAiY - Mel
1
array([2, 1, 3]) 不是行向量也不是列向量,它只是一个向量。 - user2357112
@user2357112 你应该称它为向量吗?我认为这是常见混淆的主要原因。人们通常用“向量”来指代一个[n x 1][1 x n]的对象。但我认为,关键在于一维的ndarray只有一个维度,所以我会说它不是向量,而是数组。(当然,还有一些特殊的nd数组可以被视为向量或矩阵,即当n==2时:) - Andras Deak -- Слава Україні
``[[1,2,3]]`会发生什么? - hpaulj
1个回答

5

首先了解在numpy中如何定义dot运算。

(为了简单起见,本文不讨论广播规则)当且仅当B.ndim==1时,如果A的最后一维(即A.shape[-1])与B的维数相同(即B.shape[-2]), 可以执行dot(A,B)操作。

换句话说, 如果A.shape=(N1,...,Nk,X)B.shape=(X,)。那么结果数组将具有形状(N1,...,Nk) (注意到,X已经被删除了)。

或者,如果A.shape=(N1,...,Nk,X)B.shape=(M1,...,M(j-1),X,Mj)(请注意公共的X)。那么结果数组将具有形状(N1,...,Nk,M1,...,Mj)(注意到,X已经被删除了)。

您的示例之所以能够运行,是因为它们符合规则(第一个示例符合第一个规则,第二个示例符合第二个规则):

a=numpy.asarray([[1,2,3], [4,5,6], [7,8,9]])
b=numpy.asarray([[2],[1],[3]])
a.shape, b.shape, '->', a.dot(b).shape  # X=3
=> ((3, 3), (3, 1), '->', (3, 1))

b=numpy.asarray([2,1,3])
a.shape, b.shape, '->', a.dot(b).shape  # X=3
=> ((3, 3), (3,), '->', (3,))

我建议,在使用numpy时,不要以“行向量/列向量”的思维方式进行操作,如果可能的话,根本不要考虑“向量”,而是要以“形状为S的数组”为单位进行思考。这意味着,无论是行向量还是列向量都只是“一维数组”。在numpy看来,它们是相同的。
这也应该说明为什么在您的情况下,b.transpose()与b是相同的。由于b是一个一维数组,当转置时,它仍然是一个一维数组。转置不会影响一维数组。

1
这不是 numpy.dot 处理高于2维参数的方式。我建议在你的答案中省略高维行为;dot 的高维行为并不是很有用。 - user2357112
@user2357112,感谢您指出这一点。我已经修正了我的回答。 - shx2
1
@user2357112:「点的高维行为可能对你来说不太有用」- 也许对你来说不是很有用! - ali_m
@percusse 你可以写成array([1,0,0])[:,None];) 但我理解你的意思。 - Andras Deak -- Слава Україні
1
@AndrasDeak 我选择使用 atleast_2D 和自动完成属性。 - percusse
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接