小编典典

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

python

我尝试运行如下代码:

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

矩阵返回的结果应为:

数组([[23],[53],[83]])

23
53
83

数组([23,53,83])

23 53 83

为什么会发生结果?


阅读 202

收藏
2021-01-20

共1个答案

小编典典

顾名思义,该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,1),只要形状BIS (2,1)。在这种情况下,由于A具有shape (3,2),并且B具有shape
(2,1),因此您期待有的结果形状是合理的(3,1)

但是这里B的形状为(2,),而不是(2,1)。因此,我们现在所处的领域 不在通常的矩阵乘法规则管辖范围之内
。因此,结果的真实情况完全取决于numpy.dot()函数的设计者。他们可以选择将其视为错误(“尺寸不匹配”)。取而代之的是,他们选择了应对这种情况的方法,如本答案所述

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

根据numpy,一维数组只有一个维,并且所有检查都针对该维。因此,我们发现np.dot(A,B)将A的第二维与B的一维进行比较

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

现在,唯一剩下的问题是为什么是结果形(3,)而不是(3,1)or (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,)您的示例生成的结果。

这是供您验证的代码:

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)

2021-01-20