对于Numpy,计算大小为10的向量的内积的最佳方法是什么?

2024-05-17 03:18:55 发布

您现在位置:Python中文网/ 问答频道 /正文

1. np.dot(vector1*matrix1)
2. np.array([np.dot(row,vector1) for row in matrix1])
3. np.matmul(vector1,matrix1)
4. np.dot(matrix1,vector1)
5. np.sum(matrix1*vector1,axis=1)

Tags: infornparraydotrowsumaxis
2条回答
import numpy as np 
v = np.random.random(size = 10) # vector of size 10
m = np.random.random(size = (5, 10)) # matrix of size (5, 10) 
m@v # compute inner product 

我们只使用内积运算符@。举个例子

>>> v
array([ 0.62106289,  0.53194633,  0.26856774,  0.97947622,  0.38479922,
        0.03201307,  0.51045447,  0.49990235,  0.54168934,  0.50868176])
>>> m 
array([[ 0.13075822,  0.68711111,  0.15934606,  0.44172015,  0.22615204,
         0.44816934,  0.53960113,  0.80397538,  0.50143107,  0.18997813],
       [ 0.78891921,  0.035147  ,  0.40099655,  0.33270442,  0.42478057,
         0.4145495 ,  0.84061422,  0.36837421,  0.62218952,  0.34043758],
       [ 0.96878536,  0.74850168,  0.52667831,  0.87088367,  0.28361016,
         0.4861426 ,  0.30693948,  0.81342318,  0.66667058,  0.32418454],
       [ 0.44617067,  0.87359669,  0.91079363,  0.70184155,  0.65774634,
         0.83738866,  0.29639453,  0.20157455,  0.08307142,  0.46592851],
       [ 0.85389639,  0.59084659,  0.76528861,  0.70007616,  0.23339048,
         0.49946522,  0.35635152,  0.38155495,  0.46604566,  0.00703169]])
>>> m@v
array([ 2.06914458,  2.24241604,  3.20833979,  2.48783289,  2.47033001])

在本例中,m[i]@v = (m@v)[i]表示i=0,1,2,3,4

>>> np.alltrue([(m@v)[i]==m[i]@v for i in range(m.shape[0])])
True 

另一种解决方案使用np.einsum。更容易理解的是,你过去使用过爱因斯坦的求和符号(比如微分几何或更高级的物理学)

>>> np.einsum('ij,j',m,v)
array([ 2.06914458,  2.24241604,  3.20833979,  2.48783289,  2.47033001])

首先,我们可以问哪些是有效的!

In [4]: vector1 = np.arange(10)
In [5]: matrix1 = np.arange(50).reshape(5,10)

首先使用dot的错误方法:

In [6]: np.dot(vector1*matrix1)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-c0ee48ce8d26> in <module>()
----> 1 np.dot(vector1*matrix1)

TypeError: Required argument 'b' (pos 2) not found

下一个有用的

In [7]: np.array([np.dot(row,vector1) for row in matrix1])
Out[7]: array([ 285,  735, 1185, 1635, 2085])

另一个错误的方法是-使用matmul的基本规则和使用dot的基本规则是“a的最后一个,b的第二个到最后一个”:

In [8]: np.matmul(vector1,matrix1)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-8-90d753017fdf> in <module>()
----> 1 np.matmul(vector1,matrix1)

ValueError: shapes (10,) and (5,10) not aligned: 10 (dim 0) != 5 (dim 0)

正确使用dot(A(5,10)对和A(10,)ok的方法:

In [9]: np.dot(matrix1,vector1)
Out[9]: array([ 285,  735, 1185, 1635, 2085])

还有另一个正确的方法。

In [10]: np.sum(matrix1*vector1,axis=1)
Out[10]: array([ 285,  735, 1185, 1635, 2085])

工作的结果是一样的。

[9]中的顺序也适用于matmul。它也可以写成matrix1 @ vector1

至于“最佳”,我们可以试试时机。我猜9是最快的,7是最慢的。

其中(5,10)对与(10,)的情形是(5,10)对与(10,n)产生(5,n)的典型2d情形的推广。

相关问题 更多 >