为什么2d数组和1d数组的numpy点积会生成1d数组? [英] Why does numpy Dot product of 2d array with 1d array produce 1d array?

查看:98
本文介绍了为什么2d数组和1d数组的numpy点积会生成1d数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试运行如下代码:

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

I thought the shape of np.dot(A,B) should be (1,3) not (3,).

矩阵返回的结果应为:

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

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

23
53
83

不是

array([23,53,83])

array([23,53,83])

23 53 83

为什么会出现结果?

推荐答案

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

As its name suggests, the primary purpose of the numpy.dot() function is to deliver a scalar result by performing a traditional linear algebra dot product on two arrays of identical shape (m,).

鉴于此主要目的,文档 numpy.dot()的第一篇(下面的第一个要点)也谈到了这种情况:

Given this primary purpose, the documentation of numpy.dot() also talks about this scenario as the first (the first bullet point below):

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)形状,它仍然不能完全回答您的问题.

Your case is covered by the 4 th bullet point above (as pointed out by @hpaulj) in his comments. But then, it still does not fully answer your question as to why the result has shape (3,), and not (3,1) as you expected.

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

You are justified in expecting a result-shape of (3,1), only if shape of B is (2,1). In such a case, since A has shape (3,2), and B has shape (2,1), you'd be justified in expecting a result-shape of (3,1).

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

But here, B has a shape of (2,), and not (2,1). So, we are now in a territory that's outside the jurisdiction of the usual rules of matrix multiplication. So, it's really up to the designers of the numpy.dot() function as to how the result turns out to be. They could've chosen to treat this as an error ("dimension mis-match"). Instead, they've chosen to deal with this scenario, as described in this answer.

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

I'm quoting that answer, with some modifications to relate your code:

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

According to numpy a 1D array has only 1 dimension and all checks are done against that dimension. Because of this we find that np.dot(A,B) checks second dimension of A against the one dimension of B

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

So, the check would succeed, and numpy wouldn't treat this as an error.

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

Now, the only remaining question is why is the result-shape (3,) and not (3,1) or (1,3).

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

The answer to this is: in A, which has shape (3,2), we have consumed the last part (2,) to perform sum-product. The un-consumed part of A's shape is (3,), and hence the shape of the result of np.dot(A,B), would be (3,). To understand this further, if we take a different example in which A has a shape of (3,4,2), instead of (3,2), the un-consumed part of A's shape would be (3,4,), and the result of np.dot(A,B) would be (3,4,) instead of (3,) which your example produced.

以下是供您验证的代码:

Here's the code for you to verify:

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)

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

Another helpful perspective to understand the behavior in this example is below:

形状为(3,4,2)的数组A可以在概念上可视化为内部数组的外部数组,其中外部数组的形状为(3,4),每个内部数组的形状为(2,).因此,在这些内部数组的每个数组上,将使用数组B(形状为(2,)来执行传统的点积,并且将得到的标量全部留在自己的位置,以形成(3,4)形状(因此,由所有这些就地标量结果组成的numpy.dot(A,B)的整体结果将具有形状(3,4).

The array A of shape (3,4,2) can be conceptually visualized as an outer array of inner arrays, where the outer array has shape (3,4), and each inner array has shape (2,). On each of these inner arrays, the traditional dot product will therefore be performed using the array B (which has shape (2,), and the resulting scalars are all left in their own respective places, to form a (3,4) shape (the outer matrix shape). So, the overall result of numpy.dot(A,B), consisting of all these in-place scalar results, would have the shape (3,4).

这篇关于为什么2d数组和1d数组的numpy点积会生成1d数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆