Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 矩阵和向量的元素点积_Python_Numpy_Matrix_Array Broadcasting - Fatal编程技术网

Python 矩阵和向量的元素点积

Python 矩阵和向量的元素点积,python,numpy,matrix,array-broadcasting,Python,Numpy,Matrix,Array Broadcasting,有很多类似的问题,但我真的不知道如何将它们精确地应用到我的案例中 我有一个矩阵数组和一个向量数组,我需要元素的点积。说明: In [1]: matrix1 = np.eye(5) In [2]: matrix2 = np.eye(5) * 5 In [3]: matrices = np.array((matrix1,matrix2)) In [4]: matrices Out[4]: array([[[ 1., 0., 0., 0., 0.], [ 0., 1.

有很多类似的问题,但我真的不知道如何将它们精确地应用到我的案例中

我有一个矩阵数组和一个向量数组,我需要元素的点积。说明:

In [1]: matrix1 = np.eye(5)

In [2]: matrix2 = np.eye(5) * 5

In [3]: matrices = np.array((matrix1,matrix2))

In [4]: matrices
Out[4]: 
array([[[ 1.,  0.,  0.,  0.,  0.],
        [ 0.,  1.,  0.,  0.,  0.],
        [ 0.,  0.,  1.,  0.,  0.],
        [ 0.,  0.,  0.,  1.,  0.],
        [ 0.,  0.,  0.,  0.,  1.]],

       [[ 5.,  0.,  0.,  0.,  0.],
        [ 0.,  5.,  0.,  0.,  0.],
        [ 0.,  0.,  5.,  0.,  0.],
        [ 0.,  0.,  0.,  5.,  0.],
        [ 0.,  0.,  0.,  0.,  5.]]])

In [5]: vectors = np.ones((5,2))

In [6]: vectors
Out[6]: 
array([[ 1.,  1.],
       [ 1.,  1.],
       [ 1.,  1.],
       [ 1.,  1.],
       [ 1.,  1.]])

In [9]: np.array([m @ v for m,v in zip(matrices, vectors.T)]).T
Out[9]: 
array([[ 1.,  5.],
       [ 1.,  5.],
       [ 1.,  5.],
       [ 1.,  5.],
       [ 1.,  5.]])
最后一行是我想要的输出。不幸的是,这是非常低效的,例如,做
matrix@vectors
计算由于广播而产生的不需要的点积(如果我理解得很好,它返回第一个矩阵点2个向量,第二个矩阵点2个向量)实际上更快

我想
np.einsum
np.tensordot
可能会有帮助,但我所有的尝试都失败了:

In [30]: np.einsum("i,j", matrices, vectors)
ValueError: operand has more dimensions than subscripts given in einstein sum, but no '...' ellipsis provided to broadcast the extra dimensions.

In [34]: np.tensordot(matrices, vectors, axes=(0,1))
Out[34]: 
array([[[ 6.,  6.,  6.,  6.,  6.],
        [ 0.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  0.]],

       [[ 0.,  0.,  0.,  0.,  0.],
        [ 6.,  6.,  6.,  6.,  6.],
        [ 0.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  0.]],

       [[ 0.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  0.],
        [ 6.,  6.,  6.,  6.,  6.],
        [ 0.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  0.]],

       [[ 0.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  0.],
        [ 6.,  6.,  6.,  6.,  6.],
        [ 0.,  0.,  0.,  0.,  0.]],

       [[ 0.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  0.],
        [ 6.,  6.,  6.,  6.,  6.]]])

注意:我的真实案例场景使用了比
matrix1
matrix2
更复杂的矩阵。对于
np.einsum
,您可以使用:

np.einsum("ijk,ki->ji", matrices, vectors)

#array([[ 1.,  5.],
#       [ 1.,  5.],
#       [ 1.,  5.],
#       [ 1.,  5.],
#       [ 1.,  5.]])

您可以按如下方式使用
@

matrices @ vectors.T[..., None]
# array([[[ 1.],
#         [ 1.],
#         [ 1.],
#         [ 1.],
#         [ 1.]],

#        [[ 5.],
#         [ 5.],
#         [ 5.],
#         [ 5.],
#         [ 5.]]])
正如我们所见,它计算正确的事情,但安排错误。 所以

(matrices @ vectors.T[..., None]).squeeze().T
# array([[ 1.,  5.],
#        [ 1.,  5.],
#        [ 1.,  5.],
#        [ 1.,  5.],
#        [ 1.,  5.]])

我想就是这样。我得研究一下爱因斯坦的符号,我想。。。谢谢不客气。很高兴有帮助!这同样有效,显然它与@Psidom的解决方案一样快。我会接受他的回答,因为他跑得更快,但这相当好…@nicoco对我很好。谢谢你安排时间。知道这一点很有用。