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

发布于 2021-01-29 15:02:40

我尝试运行如下代码:

>>> 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

为什么会发生结果?

关注者
0
被浏览
99
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    顾名思义,该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)



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看