Numpy向量函数

这是我在这学期第一节课上展示的一个例子。

进口matplotlib。import numpy = np. lang (-np. lang)π,np。Pi, 0.01) s = np.sin(t) plt。Plot (t, s) Plot .show()

本例使用numpy和pyplot的组合来构造曲线y = sinx的图。正如您从前面对pyplot的讨论中所知道的,plot()方法需要两个参数。第一个是要绘制的一组点的x坐标列表,而第二个是这些点的y坐标列表。事实证明,plot()将接受除了普通列表之外的其他东西。Plot()也将接受任何可迭代的对象作为其参数。

在本例中,我们准备并传递给plot()的参数都是numpy数组对象。为了构造数组t,我们使用numpy range()方法。range()接受三个参数:起始点、结束点和步长,并为行向量返回一个数组对象。行向量包含请求范围内赢博体育样本点的列表。在本例中,样本点列表包含超过600个点,间隔0.01个单位。

线

S = np, sin(t)

然后实现numpy所称的矢量操作。这个操作将函数sinx赢博体育于向量t中的每个x值,得到一个包含我们绘图所需的y值的新向量s。

Numpy包含大量这样的向量函数。这些函数中的每一个都将接受一个向量作为参数,并返回一个新向量,该新向量的元素是依次将该函数赢博体育于每个原始元素的结果。除了这些向量函数之外,numpy还重载几乎赢博体育算术运算符来实现向量算术运算。

这是最后一个例子的一个稍微花哨的版本。在这个版本中,我们将使用numpy向量函数来代替y = 3sin (x - 2)的绘图:

进口matplotlib。import numpy = np. lang (-np. lang)π,np。Pi, 0.01) s = 3*np.sin(t-2)Plot (t, s) Plot .show()

本例中的算术运算符对numpy数组中的每个条目赢博体育标量转换。例如,t-2生成一个新的数组,它的每一个元素都是t中的一个元素减去标量2。

聚合函数

Numpy向量操作在与聚合函数结合使用时才真正发挥作用。最简单和最强大的聚合函数是sum(),它返回向量中赢博体育元素的和。

下面是一个早先的例子,它被重写以利用numpy向量操作。这个例子就是我之前讲过的隆伯格积分的例子。Romberg积分的第一步是通过公式计算梯形规则估计

这个公式的另一种写法是,除了求和中的第一项和最后一项,每个样本点在这里出现两次。我们可以把这个和写成

为了计算这个表达式中心的和,我们首先创建一个numpy数组,表示a和b之间的赢博体育样本点。然后我们将该数组传递给向量函数f(x)*h,然后赢博体育sum()操作将赢博体育这些项相加。

下面是完整示例的代码,将计算梯形规则的逻辑替换为numpy向量求值代码。

这是我们将在本例中使用的函数def (x):返回np.sqrt(4.0 - (2.0-x)*(2.0-x)) #通过使用步长为(b-a)/N的梯形#计算f(x)从a到b的积分#的近似值def梯形(a,b,N): h = (b-a)/N;x = np. ranange (a,b,h) return h*(f(x).sum()) - h*f(a)/2 - h*f(b)/2 #递归定义的Romberg公式与缓存# r_int将计算R[k,j],但记住# result在R列表中以加快后续计算。def r_int(a,b,k,j,R): if R[k][j] != -1: #我们以前见过这个k,j吗?返回R [k] [j] #如果是,就返回缓存的值#如果没有,计算,缓存,并返回结果如果j = = 1: R [k] [j] = trapezoidArea (a, b, 2 * * (k - 1)) elif k <珍:R [k] [j] = 0: R [k] [j] = r_int (a, b, k, j - 1, R) + (r_int (a, b, k, j - 1, R) -r_int (a, b, k - 1、j - 1 R)) / (4 * * (j - 1) 1)返回R [k] [j] . def伯格(a, b, k, j): R = [[1 c的范围(j + 1)] R的范围(k + 1)]返回r_int (a, b, k, j, R)打印(“j估计错误”);对于range(3,22,2)中的j: estimate = romberg(0.0,2.0,j,j) error = np.fabs(np。π-估计)打印(“{:> 3 d} {: f} {: .16f}”.format (j、估计、错误))

Numpy矢量代码速度快

除了允许我们对梯形规则等赢博体育一些巧妙的优化之外,使用numpy向量操作还有一个更令人信服的理由。这些操作经过了高度优化,以便在实践中尽可能快地运行。矢量代码利用的一个特殊技巧是并行化。在具有多个处理核心的机器上(目前大多数机器都是这样),numpy将执行向量操作并将其分解为块,在单独的处理器核心上运行每个块的计算。例如,在四核机器上,numpy将其处理的每个向量拆分为四个大小相等的子向量,然后在四个单独的核心上为这些单独的部分执行计算。净效果是,我们所做的每个向量操作的速度都提高了大约四倍。

通过运行Romberg程序的普通版本和numpy版本,您可以立即看到这一点。numpy版本明显更快。