
2.2 数组元素运算
ufunc(universal function)是对数组中每个元素运算的函数,比循环处理速度更快且写法简单。Numpy提供了很多数组相关的ufunc方法,同时也支持自定义ufunc函数。Numpy提供的ufunc函数分为一元函数(Unary ufuncs)和二元函数(Binary ufuncs)。
2.2.1 一元函数
一元函数是参数为单个值或者单个数组的函数,如取整、三角函数等,常用的函数如表2.1所示。
表2.1 Numpy常用一元函数

一元函数的使用方法与一般函数的相同,形如:
2.2.2 二元函数
二元函数是参数为两个数组的函数,包括算术运算和布尔运算。
1.算术运算
本例中利用四则运算符实现两个数组间的算术运算,并返回新数组。先定义数组:

两个数组相加:

两个数组相减:

两个数组相乘:

两个数组相除:

两个数组整除:

两个数组整除取余数:

2.布尔运算
布尔运算是指使用“>”“<”“>=”“<=”“==”“!=”等逻辑运算符比较两个数组,并返回布尔型数据,其中每个元素是两个数组中对应数据比较的结果。

2.2.3 广播
前面介绍了当两个数组形状相同时,可以进行算术运算和布尔运算,具体方法是两个数组对应位置的数据运算。而当它们的形状不同时,数据就会将自动扩展对齐维数较大的数组后,再进行运算,这种从低维向高维的自动扩展被称为广播(broadcasting)。
最常见的广播形式如下,即它将被减数1扩展成为与减数形状相同的数组[1,1,1]后,再进行二元减法运算:

相对复杂的是对多维数组的广播,具体沿哪一个轴扩展取决于待扩展数组的形状,简单的规则是它会沿缺失的方向扩展。首先构造数据:

当纵轴向缺少数据时,向纵轴方向扩展,如图2.1所示。

图2.1 纵向扩展示意图
当第二个数组中仅有一行数据时,自动扩展为两行,第二行的内容与第一行相同,扩展之后再进行后续运算。

当横轴向缺少数据时,向横轴方向扩展,如图2.2所示。

图2.2 横向扩展示意图
当第二个数组中仅有一列数据时,自动扩展为两列,第二列的内容与第一列相同,扩展之后再进行后续运算。

2.2.4 自定义ufunc函数
自定义ufunc函数包括两个主要步骤:第一步,定义函数,其方法和定义普通函数的方法相同。第二步,利用np.frompyfunc将函数转换为元素运算函数,它的第二个和第三个参数分别为之前定义的普通函数的入参和返回值个数。定义好之后,就可以将数组作为参数和其他参数一起调用函数了。
本例程中的函数实现了数值分段:传入的数值如果小于low则返回-1,如果大于high则返回1,否则返回0。

函数调用部分生成了包含1~9的数组x,将其代入函数。当调用函数时,x是数组,而定义的处理函数中x为每个元素。从返回结果可以看到,调用函数后返回的y为数组。
