为什么2d数组和1d数组的numpy点积会生成1d数组?

时间:2019-02-17 04:21:59

标签: python numpy

我尝试运行如下代码:

>>> 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,)。

矩阵返回的结果应为:

array([[23],[53],[83]])

23
53
83

不是

array([23,53,83])

23 53 83

为什么会出现结果?

4 个答案:

答案 0 :(得分:4)

顾名思义,numpy.dot()函数的主要目的是通过在两个形状相同的{{1}阵列上执行传统线性代数点积来提供标量结果}。

鉴于此主要目的,(m,)的{​​{3}}还将这种情况称为第一种情况(下面的第一个要点):

numpy.dot()

您的案件已在他的评论的上方第4点(如@hpaulj所指出)中涵盖。 但是,对于结果为何具有形状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. 而不是您期望的(3,),它仍然不能完全回答您的问题。

只有当(3,1)的形状为(3,1)时,您才有理由期待B的结果形状。在这种情况下,由于(2,1)的形状为A,而(3,2)的形状为B,因此期望结果形状为(2,1)是有道理的

但是这里(3,1)的形状为B,而不是(2,)。因此,我们现在位于通常的矩阵乘法规则管辖范围之外的地区。因此,结果的最终结果实际上取决于(2,1)函数的设计者。他们可以选择将其视为错误(“尺寸不匹配”)。相反,他们选择处理这种情况,如documentation中所述。

我引用了该答案,并做了一些修改以关联您的代码:

  

根据numpy,一维数组仅具有1维和所有检查   是针对该维度完成的。因此,我们发现np.dot(A,B)   将A的第二维与B的一维进行比较

因此,检查将成功,并且numpy不会将其视为错误。

现在,唯一剩下的问题是为什么结果形状为numpy.dot()而不是(3,)(3,1)

对此的答案是:在形状为(1,3)的{​​{1}}中,我们有A的最后一部分(3,2)执行求和积。 A的形状的consumed部分为(2,),因此un-consumed的结果形状为(3,)。为了进一步理解这一点,如果我们采用另一个示例,其中np.dot(A,B)的形状为(3,),而不是A的形状是(3,4,2)的未消耗部分将会是(3,2),而A的结果将是(3,4,),而不是您的示例生成的np.dot(A,B)

以下是供您验证的代码:

(3,4,)

此输出为:

(3,)

了解此示例中行为的另一个有用观点如下:

形状为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,每个内部数组的形状均为{{1 }}。因此,在这些内部数组的每一个上,将使用数组(3,4,2)(形状为(3,4)来执行传统的点积,并将得到的标量全部留在各自的位置,以形成{ {1}}形状(外部矩阵形状)。因此,由所有这些就地标量结果组成的(2,)的整体结果将具有B的形状。

答案 1 :(得分:2)

在Wiki

enter image description here

所以(2,1)的(3,2)点将是(3,1)


如何修复

np.dot(A,B[:,None])
Out[49]: 
array([[23],
       [53],
       [83]])

答案 2 :(得分:0)

A.shape为(3,2),B.shape为(2,)这种情况可以直接将规则#4用于点操作np.dot(A,B):

  

如果a是N-D数组,b是1-D数组,则它是a和b的最后一个轴上的和积。

因为对齐将发生在B的2(仅B的轴)和A的2(A的最后一个轴)之间,并且2的确等于2,因此numpy将判断这对于点运算绝对是合法的。因此,这两个“ 2”被“消耗”,而A的(3,)处于“野外”状态。因此,(3,)将是结果的形状。

答案 3 :(得分:0)

我刚刚从Neural Network学习了这个点产品... 无论如何,它是“ 1d ”数组和“ nd ”数组之间的点积。 enter image description here

如我们所见,它在红色框中分别计算元素的乘法总和为“ 1 7 + 2 8” 然后enter image description here

然后enter image description here