Python 为什么2d阵列和1d阵列的numpy点积会产生1d阵列?
我尝试运行以下代码:Python 为什么2d阵列和1d阵列的numpy点积会产生1d阵列?,python,numpy,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)
>>> 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])
为什么会出现这种结果?在wiki中
所以带(2,1)的(3,2)点将是(3,1)
如何修复
np.dot(A,B[:,None])
Out[49]:
array([[23],
[53],
[83]])
在维基
所以带(2,1)的(3,2)点将是(3,1)
如何修复
np.dot(A,B[:,None])
Out[49]:
array([[23],
[53],
[83]])
顾名思义,
numpy.dot()
函数的主要目的是通过在两个形状相同的数组(m,)
上执行传统线性代数点积来传递标量结果
鉴于这一主要目的,numpy.dot()
的作者也将此场景作为第一个场景(下面的第一个要点):
您的案例包含在上述第四点中(正如@hpaulj在其评论中指出的)。
但是,它仍然不能完全回答您的问题,即为什么结果的形状是(3,)
,而不是您所期望的(3,1)
只有当B
的形状为(2,1)
时,您才有理由期望结果形状为(3,1)
。在这种情况下,由于a
具有形状(3,2)
,而B
具有形状(2,1)
,因此您有理由期望结果形状为(3,1)
但是在这里,B
的形状是(2,)
,而不是(2,1)
。因此,我们现在处于一个超出矩阵乘法通常规则管辖范围的领域。因此,结果如何取决于numpy.dot()
函数的设计者。他们可以选择将此视为错误(“维度不匹配”)。相反,他们选择了处理这种情况,如中所述
我引用了这个答案,并对代码进行了一些修改:
根据numpy,1D数组只有一个维度和所有检查
都是针对那个维度做的。正因为如此,我们发现np.dot(A,B)
检查A的第二个维度与B的第一个维度
因此,检查将成功,numpy不会将此视为错误
现在,唯一剩下的问题是为什么结果形状是(3,)
,而不是(3,1)
或(1,3)
答案是:在具有形状(3,2)
的A
中,我们使用了最后一部分(2,)
来执行和积。A的形状的未消耗的部分是(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)
另一个有助于理解本例中行为的视角如下:
形状(3,4,2)
的数组A
可以在概念上可视化为内部数组的外部数组,其中外部数组具有形状(3,4)
,并且每个内部数组具有形状(2,)
。因此,在每个内部阵列上,将使用阵列B
(具有形状(2,)
)执行传统的点积,得到的标量都保留在各自的位置,以形成(3,4)
形状(外部矩阵形状)。因此,numpy.dot(a,B)的总体结果
由所有这些就地标量结果组成,其形状为(3,4)
顾名思义,numpy.dot()
函数的主要目的是通过对两个形状相同的数组(m,)
执行传统线性代数点积来传递标量结果
鉴于这一主要目的,numpy.dot()
的作者也将此场景作为第一个场景(下面的第一个要点):
您的案例包含在上述第四点中(正如@hpaulj在其评论中指出的)。
但是,它仍然不能完全回答您的问题,即为什么结果的形状是(3,)
,而不是您所期望的(3,1)
只有当B
的形状是(2,1)
时,您才有理由期望结果形状为(3,1)
。在这种情况下,由于a
具有形状(3,2)
,并且B
具有形状(2,1)
,因此您有理由期望结果形状为(3,1)
但是在这里,B
的形状是(2,)
,而不是(2,1)
。因此,我们现在处于一个超出矩阵乘法通常规则管辖范围的领域。因此,这实际上取决于numpy.dot()的设计者
函数的作用是确定结果如何。他们可以选择将此视为错误(“维度不匹配”)。相反,他们选择处理此场景,如中所述
我引用了这个答案,并对代码进行了一些修改:
根据numpy,1D数组只有一个维度和所有检查
正因为如此,我们发现np.dot(A,B)
检查A的第二个维度与B的第一个维度
因此,检查将成功,numpy不会将此视为错误
现在,唯一剩下的问题是为什么结果形状是(3,)
,而不是(3,1)
或(1,3)
答案是:A
,它的形状是(3,2)
,我们有
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)