数组的点积可以通过 NumPy 库的 linalg.multi_dot 函数来计算,该函数比其前身 更容易计算并且需要更少的计算时间np.dot
。
我们还将在这篇文章中看到np.dot
和的比较multi_dot
。
在本文中查找您需要了解的有关如何使用 np dot() 计算数组和向量的点积的所有内容。
什么是点积?
点积是两个长度相同的数组之间的数学运算,返回标量值。它的计算方式为两个数组的逐元素乘积之和。其给出如下:dot(a, b)[i,j,k,m] = sum(a [i,j,:] * b[k,:,m])
关于 linalg.multi_dot 您需要了解的一切
NumPy 库的这个函数很方便,因为它可以在单个函数调用中计算两个或多个数组的点积。
单一函数调用是指在计算两个或多个数组的点积时,无需在不同的函数调用中分别计算数组的点积,然后将结果合并到另一个函数调用中。我们只需调用一次函数即可计算尽可能多的数组的点积。
multi_dot 可以被认为是:
def mulit_dot(arrays): return functools.reduce(np.dot, arrays)
句法:
linalg.multi_dot(
arrays
,
*
,
out=None
)
论据 | 描述 | 默认值 | 必需/可选 |
数组 | 如果第一个参数是一维,则将其视为行向量。如果最后一个参数是一维,则将其视为列向量 生成 的数组具有与第一个参数相同的行数和与第二个参数相同的列数 |
类似数组的序列 | 必需的 |
出去 | 输出参数。它通常不会在语法中指定,但是当指定时,计算的输出应该与此字段中指定的类型和内存布局相同。此参数的目的是重用现有的 NumPy 数组作为输出参数 ,这可以提高性能如果不满足参数 的指定条件,函数将引发异常 out |
ndarray | 选修的 |
multi_dot
返回:此函数返回给定数组的点积作为输入。输出是一个 NumPy 数组。
两个简单数组的点积
让我们计算两个简单二维矩阵的点积。
代码如下。
1
2
3
4
5
6
7
|
import numpy as np #creating two arrays a = np.array([[ 1 , 2 ],[ 3 , 4 ]]) b = np.array([[ 5 , 6 ],[ 7 , 8 ]]) #computing the dot product comp = np.linalg.multi_dot([a, b]) print (comp) |
import numpy as np
:我们正在导入具有别名的 NumPy 库 – np.
在第三行和第四行中,使用函数创建了两个数组np.array
,并将其存储在两个不同的变量 a 和 b 中。
a 和 b 的点积是在 的帮助下计算的np.linalg.multi_dot
,并存储在第六行中名为 comp 的变量中。
在下一行中,我们将打印点积的结果。
a 和 b 的点积如下所示。/
让我们检查一下执行所需的时间。
1
2
|
#checking the execution time % timeit np.linalg.multi_dot([a, b]) |
该%timeit
函数用于计算执行此操作所需的时间。
现在我们已经了解了基本功能,让我们看一个更复杂的示例。
当其中一个数组具有无穷值时,两个数组的点积
让我们首先考虑一个具有正无穷大值的数组。
当我们处理无穷值的消除时,这里有一篇文章展示了如何在 python 中创建无穷值。
代码如下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
import numpy as np #creating arrays a = np.array([[ 3 ,np.inf],[ 4 , 5 ]]) b = np.array([[ 5 , 6 ],[ 7 , 8 ]]) print ( "The first array is:\n" ,a) print ( "-" * 15 ) print ( "The second array is :\n" ,b) print ( "-" * 15 ) #converting the infintiy values to some number a1 = np.nan_to_num(a,posinf = 12 ) print ( "Modified array :\n" ,a1) print ( "*" * 15 ) comp1 = np.linalg.multi_dot([a1, b]) print ( "The dot product of two arrays is:\n" ,comp1) |
import numpy as np
:我们正在导入具有别名的 NumPy 库 – np.
在第三行中,我们创建一个二维数组,其中包含一个正无穷值。该关键字np.inf
用于创建正无穷大值。该数组存储在一个名为 a 的变量中。
在第四行中,我们创建一个二维数组,该数组存储在名为 b 的新变量中。
在下一行中,我们将第一个数组打印到屏幕上。
print("-"*15)
用作分隔符。它在屏幕上打印 15 个连字符 (-)。
在第 7 行中,我们将第二个数组打印到屏幕上。
print("-"*15)
用作分隔符。它在屏幕上打印 15 个连字符 (-)。
现在我们有两个数组 a 和 b。但我们需要用某个数字替换正无穷大值。可以使用np.nan_to_num
方法通过传递我们需要修改的数组 (a) 和我们希望替换无穷大的数字(在本例中为 12)来完成。posinf
用于指定我们给出的数字是正数。
修改后的数组存储在 a1 中并作为参数传递给函数multi_dot
。
点积的结果存储在 comp1 中并在第 14 行打印。
输出是:
让我们看看点积是否适用于负值。
代码如下所示。
import numpy as np #creating arrays a = np.array([[ 3 , 6 ],[ 4 , 5 ]]) b = np.array([[ 5 , - np.inf],[ 7 , 8 ]]) print ( "The first array is:\n" ,a) print ( "-" * 15 ) print ( "The second array is :\n" ,b) print ( "-" * 15 ) #converting the infintiy values to some number b1 = np.nan_to_num(b,neginf = - 13 ) print ( "Modified array :\n" ,b1) print ( "*" * 15 ) comp2 = np.linalg.multi_dot([a, b1]) print ( "The dot product of two arrays is:\n" ,comp2) |
import numpy as np
:我们正在导入具有别名的 NumPy 库 – np.
在第三行中,我们创建一个二维数组,该数组存储在一个名为 a 的新变量中。
在第四行中,我们创建一个二维数组,其中包含一个负无穷值。关键字 –np.inf
用于创建负无穷大值。该数组存储在名为 b 的变量中。
在下一行中,我们将第一个数组打印到屏幕上。
print("-"*15)
用作分隔符。它在屏幕上打印 15 个连字符 (-)。
在第 7 行中,我们将第二个数组打印到屏幕上。
print("-"*15)
用作分隔符。它在屏幕上打印 15 个连字符 (-)。
我们需要用某个数字替换负无穷大值。可以使用np.nan_to_num
方法通过传递我们需要修改的数组 (b) 和我们希望替换无穷大的数字(在本例中为 -13)来完成。neginf
用于指定我们给出的数字是负数。
修改后的数组存储在 b1 中并作为参数传递给函数multi_dot
。
点积的结果存储在 comp1 中并在第 14 行打印。
计算的点积如下:
三个三维数组的点积
让我们考虑三个 3×3 维度的矩阵。
这是代码。
import numpy as np #creating three matrices a = np.array([[ 1 , 2 , 3 ], [ 4 , 5 , 6 ], [ 7 , 8 , 9 ]]) print ( "First 3x3 matrix:\n" ,a) print ( "-" * 15 ) b = np.array([[ 9 , 0 , 1 ], [ 1 , 5 , 4 ], [ 8 , 1 , 0 ]]) print ( "Second 3x3 matrix:\n" ,b) print ( "-" * 15 ) c = np.array([[ 1 , 0 , 0 ], [ 0 , 1 , 0 ], [ 0 , 0 , 1 ]]) print ( "Third 3x3 matrix:\n" ,c) print ( "*" * 15 ) #calculating the dot product comp3 = np.linalg.multi_dot([a,b,c]) print ( "The dot product is:" ) print (comp3) |
在第一行中,我们将 NumPy 库引入到环境中。
三维数组可以被认为是三个列表组合在一起形成一个矩阵。
在第三行中,我们创建第一个数组并将其存储在变量 a 中。
在下一行中,我们在屏幕上打印数组。这\n
是一个换行符。之后的所有参数都\n
打印在新行中。
print("-"*15)
:该行用于创建分隔符并在屏幕上输出 15 个连字符 (-)。
以下行用于创建存储在 b 中的第二个矩阵。
我们正在屏幕上打印新的数组。
我们正在创建第三个数组并将其存储在第九行中名为 c 的变量中,
第 13 行计算三个数组(a、b 和 c)的点积,并将其存储在名为 comp3 的变量中。
最后,我们在第 14 行打印结果。
输出如下所示。
np.dot 和 multi_dot 所花费的执行时间
让我们比较一下两种方法的执行时间:np.dot
和multi_dot
。
这是代码np.dot
1
2
3
4
5
6
7
8
9
10
11
12
|
#using np.dot import numpy as np #Creating arrays a = np.array([[ 1 , 3 ], [ 4 , 6 ]]) b = np.array([[ 5 , 6 ], [ 7 , 9 ]]) c = np.array([[ 6 , 1 ], [ 3 , 4 ]]) #computing the dot product comp1 = np.dot(a, b) res = np.dot(comp1,c) print ( "Dot products of these 3 arrays is:" ) print (res) % timeit np.dot(a,b,c) |
我们分别在第 4,5 和 6 行创建三个数组 a、b 和 c。
由于我们使用的是np.dot
,因此我们无法立即将所有三个数组作为参数传递给函数。因此,我们计算前两个数组(a 和 b)的点积,并将结果存储在名为 comp1 的变量中。
现在, comp1 和数组 c 作为参数传递给np.dot
,三个矩阵的点积存储在 res 中。
在第 11 行,我们打印结果。
np.dot
在第 12 行中,我们正在计算使用 magic 命令的执行时间%timeit
。
输出如下所示。
正如您所看到的,所花费的时间np.dot
不到 3 微秒。
让我们看看 的代码multi_dot
。
1
2
3
4
5
6
7
8
9
10
11
|
#using multi_dot import numpy as np #Creating arrays a = np.array([[ 1 , 3 ], [ 4 , 6 ]]) b = np.array([[ 5 , 6 ], [ 7 , 9 ]]) c = np.array([[ 6 , 1 ], [ 3 , 4 ]]) #computing the dot product comp2 = np.linalg.multi_dot([a, b, c]) print ( "Dot products of these 3 arrays is:" ) print (comp2) % timeit np.linalg.multi_dot([a, b, c]) |
我们分别在第 4,5 和 6 行创建三个数组 a、b 和 c。
由于我们使用的是multi_dot
,因此我们不需要多次计算点积。我们可以将所有三个数组传递给函数并在单个函数调用中获得点积。
结果存储在名为 comp2 的变量中。
在最后一行,我们检查multi_dot
using 的执行时间%timeit
。
从两个输出中观察到,multi_dot
花费的时间几乎是 的 2 倍np.dot
。
结论
我们已经了解了什么是点积以及multi_dot
函数如何使我们能够在单个函数调用中计算两个或多个数组的点积。我们还看到了 的语法multi_dot()
。
在第一个示例中,我们计算了两个二维大小的简单矩阵的点积。
接下来,我们了解了当一个数组具有无限值(正值和负值)时如何计算点积。
我们还看到了三维数组点积的计算。
最后,我们比较了np.dot
和multi_dot
。虽然multi_dot
可以帮助我们在一次调用中计算两个或多个数组的点积,但np.dot
执行时间要少得多。
因此,可以肯定地说,np.dot
和之间的选择multi-dot
取决于用例和数组的大小。
如果数组很简单并且维度较小,np.dot
则可以使用它们。但如果数组的维度更高(例如 4d),我们需要选择multi_dot
.