我尝试运行如下代码:
>>> import numpy as np >>> A = np.array([[1,2], [3,4], [5,6]]) >>> A.shape (3, 2) >>> B = np.array([7,8]) >>> B.shape (2,) >>> np.dot(A,B) array([23, 53, 83])
我认为的形状np.dot(A,B)应为(1,3)而不是(3,)。
np.dot(A,B)
矩阵返回的结果应为:
数组([[23],[53],[83]])
23 53 83
不
数组([23,53,83])
为什么会发生结果?
顾名思义,该numpy.dot()函数的主要目的是通过在两个形状相同的数组上执行 传统的线性代数点积 来提供标量结果(m,)。
numpy.dot()
(m,)
鉴于这一主要目的,在文档中numpy.dot()也对这种情况下的第一(第一子弹下方点)谈到:
numpy.dot(a, b, out=None) 1. If both a and b are 1-D arrays, it is inner product of vectors (without complex conjugation). 2. If both a and b are 2-D arrays, it is matrix multiplication, but using matmul or a @ b is preferred. 3. If either a or b is 0-D (scalar), it is equivalent to multiply and using numpy.multiply(a, b) or a * b is preferred. 4. If a is an N-D array and b is a 1-D array, it is a sum product over the last axis of a and b.
您的案件已在他的评论的上方第4点(如@hpaulj所指出)中涵盖。但是,它仍然不能完全回答您的问题,即为什么结果具有形状(3,),而不是(3,1)您期望的那样。
(3,)
(3,1)
你有理由期待中的结果形状(3,1),只要形状BIS (2,1)。在这种情况下,由于A具有shape (3,2),并且B具有shape (2,1),因此您期待有的结果形状是合理的(3,1)。
B
(2,1)
A
(3,2)
但是这里B的形状为(2,),而不是(2,1)。因此,我们现在所处的领域 不在通常的矩阵乘法规则管辖范围之内 。因此,结果的真实情况完全取决于numpy.dot()函数的设计者。他们可以选择将其视为错误(“尺寸不匹配”)。取而代之的是,他们选择了应对这种情况的方法,如本答案所述。
(2,)
我引用了该答案,并做了一些修改以关联您的代码:
根据numpy,一维数组只有一个维,并且所有检查都针对该维。因此,我们发现np.dot(A,B)将A的第二维与B的一维进行比较
因此,检查将成功,并且numpy不会将其视为错误。
现在,唯一剩下的问题是为什么是结果形(3,)而不是(3,1)or (1,3)。
(1,3)
答案是:在中A,形状为(3,2),我们具有执行求和积consumed的最后一部分(2,)。在un- consumedA的形状的一部分是(3,),因此结果的形状np.dot(A,B),会(3,)。为了进一步理解这一点,如果我们采用一个A形状为(3,4,2)而不是的其他示例,则该形状(3,2)的未消耗部分A将为(3,4,),而结果的结果np.dot(A,B)将(3,4,)代替(3,)您的示例生成的结果。
consumed
un- consumed
(3,4,2)
(3,4,)
这是供您验证的代码:
import numpy as np A = np.arange(24).reshape(3,4,2) print ("A is:\n", A, ", and its shape is:", A.shape) B = np.array([7,8]) print ("B is:\n", B, ", and its shape is:", B.shape) C = np.dot(A,B) print ("C is:\n", C, ", and its shape is:", C.shape)
输出为:
A is: [[[ 0 1] [ 2 3] [ 4 5] [ 6 7]] [[ 8 9] [10 11] [12 13] [14 15]] [[16 17] [18 19] [20 21] [22 23]]] , and its shape is: (3, 4, 2) B is: [7 8] , and its shape is: (2,) C is: [[ 8 38 68 98] [128 158 188 218] [248 278 308 338]] , and its shape is: (3, 4)
下面是了解该示例中行为的另一个有用的观点:
A形状数组(3,4,2)可以在概念上可视化为内部数组的外部数组,其中外部数组具有shape (3,4),而每个内部数组都具有shape (2,)。因此,在这些内部数组的每一个上,都将使用该数组B(具有shape (2,),并且将生成的标量全部留在自己的位置)以形成(3,4)形状(外部矩阵形状)来执行传统的点积。numpy.dot(A,B)由所有这些就地标量结果组成的整体结果将具有的形状(3,4)。
(3,4)
numpy.dot(A,B)