NumPy数组使你可以将许多种数据处理任务表述为简洁的数组表达式(否则需要编 写循环)。用数组表达式代替循环的做法,通常被称为矢量化。一般来说,矢量化 数组运算要比等价的纯Python方式快上一两个数量级(甚至更多),尤其是各种数值计算。
作为简单的例子,假设我们想要在一组值(网格型)上计算函数 sqrt(x^2+y^2) 。np.meshgrid函数接受两个一维数组,并产生两个二维矩阵(对应于两个数组中所有的(x,y)对):
现在,对该函数的求值运算就好办了,把这两个数组当做两个浮点数那样编写表达式即可:
一、数组的条件逻辑运算
假设我们有一个布尔数组和两个值数组,我们想要根据cond中的值选取xarr和yarr的值:当cond中的值为True时,选取xarr的值,否则从yarr中选取。
使用列表推导可以实现:
这有几个问题。第一,它对大数组的处理速度不是很快(因为所有工作都是由纯
Python完成的)。第二,无法用于多维数组
numpy.where函数是三元表达式x if condition else y的矢量化版本,若使用np.where,则可以将该功能写得非常简洁:
在数据分析工作中,where通常用于根据另一个数组而产生一个新的数组。
假设有一个由随机数据组成的矩阵,你希望将所有正值替换为2,将所有负值替换为-2。若利用np.where,则会非常简单:
使用np.where,可以将标量和数组结合起来。传递给where的数组大小可以不相等,甚至可以是标量值。
例如,我可用常数2替换arr中所有正的值:第 4 章 NumPy 基础:数组和矢量计算
二、数学和统计方法
可以通过数组上的一组数学函数对整个数组或某个轴向的数据进行统计计算。
表4-5列出了全部的基本数组统计方法。后续章节中有很多例子都会用到这些方法。
这类统计函数的调用方法有两种:
arr.mean() 或者 np.mean(arr)
例如:
这类的函数可以接受一个axis选项参数,用于计算该轴向上的统计值,最终结果是一个少一维的数组:
- axis=1:表示列方向,即对行的统计
- axi=0:表示行方向,即对列的统计。
这里,arr.mean(1)是“计算行的平均值”,arr.sum(0)是“计算每列的和”。
其他如cumsum和cumprod之类的方法则不聚合,而是产生一个由中间结果组成的 数组:
在多维数组中,累加函数(如cumsum)返回的是同样大小的数组,但是会根据每个低维的切片沿着标记轴计算部分聚类:
三、用于布尔型数组的方法
在上面这些方法中,布尔值会被强制转换为1(True)和0(False)。因此,sum经常被用来对布尔型数组中的True值计数:
另外还有两个方法any和all,它们对布尔型数组非常有用。
- any用于测试数组中是否存在一个或多个True
- 而all则检查数组中所有值是否都是True
这两个方法也能用于非布尔型数组,所有非0元素将会被当做True。
四、排序
跟Python内置的列表类型一样,NumPy数组也可以通过sort方法就地排序:
多维数组可以在任何一个轴向上进行排序,只需将轴编号传给sort即可:
顶级方法np.sort返回的是数组的已排序副本,而就地排序则会修改数组本身。
计算数组分位数最简单的办法是对其进行排序,然后选取特定位置的值:
五、数组的集合运算
NumPy提供了一些针对一维ndarray的基本集合运算
最常用的可能要数np.unique了,它用于找出数组中的唯一值并返回已排序的结果:
另一个函数np.in1d用于测试一个数组中的值在另一个数组中的成员资格,返回一个布尔型数组: