创建ndarray
创建数组最简单的办法就是使用array函数。它接受一切序列型的对象(包括其他数组),然后产生一个新的含有传入数据的Numpy数组。以一个列表的转换为例。
嵌套序列(比如由一组等长列表组成的列表)将会被转换为一个多维数组:
NumPy数组arr2的两个维度的shape是从data2引入的。可以用属性ndim和shape验证:
除np.array之外,还有一些函数也可以新建数组。比如,zeros和ones分别可以创建指定长度或形状的全0或全1数组。empty可以创建一个没有任何具体值的数组。要用这些方法创建多维数组,只需传入一个表示形状的元组即可:
np.zero(size)
np.ones(size)
np.arange(num)
array 的数据类型
除非特别说明,np.array会尝试为新建的这个数组推断出一个较为合适的数据类型。数据类型保存在一个特殊的dtype对象中。比如说,在上面的两个例子中,我们有:
通过ndarray的astype方法明确地将一个数组从一个dtype转换成另一个dtype:
整数转换成浮点数
浮点数转换成整数,如果将浮点数转换成整数,则小数部分将会被截取删除:
如果某字符串数组表示的全是数字,也可以用astype将其转换为数值形式:
Numpy数组的运算
数组很重要,因为它使你不用编写循环即可对数据执行批量运算。NumPy用户称其为矢量化(vectorization)。大小相等的数组之间的任何算术运算都会将运算应用到元素级:
数组与标量的算术运算会将标量值传播到各个元素:
大小相同的数组之间的比较会生成布尔值数组
不同大小的数组之间的运算叫做广播(broadcasting)
基本的索引和切片
一维数组与python的列表差不多
跟列表最重要的区别在于,数组切片是原始数组的视图。这意味着数据不会被复制,视图上的任何修改都会直接反映到源数组上。
修改arr_slice中的值,变动也会体现在原始数组arr中
在二维数组中,各索引位置上的元素不再是标量而是一维数组:
下面两种方式是等价的
在多维数组中,如果省略了后面的索引,则返回对象会是一个维度低一点的ndarray
标量值和数组都可以被赋值给arr3d[0]:
二维切片
可以看出,它是沿着第0轴(即第一个轴)切片的。也就是说,切片是沿着一个轴向选取元素的。表达式arr2d[:2]可以被认为是“选取arr2d的前两行”。
传入多个切片,arr2d[:2, :2]选取二维数组的前两行,前两列
布尔型索引
假设每个名字都对应data数组中的一行,而我们想要选出名字“Bob”的所有行。跟算术运算一样,数组的比较运算(如==)也是矢量化的。因此,对names和字符串"Bob"的比较运算将会产生一个布尔型数组:
要选择除"Bob"以外的其他值,既可以使用不等于符号(!=),也可以通过~对条件进行否定:
~操作符用来反转条件
选取这三个名字中的两个需要组合应用多个布尔条件,使用&(和)、|(或)之类的布尔算术运算符即可:
通过布尔型数组设置值是一种经常用到的手段。为了将data中的所有负值都设置为0,我们只需:
通过一维布尔数组设置整行或列的值也很简单:
花式索引
花式索引(Fancy indexing)是一个NumPy术语,它指的是利用整数数组进行索引。假设我们有一个8×4数组:
为了以特定顺序选取行子集,只需传入一个用于指定顺序的整数列表或ndarray即可:
使用负数索引将会从末尾开始选取行:
一次传入多个索引数组会有一点特别。它返回的是一个一维数组,其中的元素对应各个索引元组:
数组转置和轴对换
转置是重塑的一种特殊形式,它返回的是源数据的视图(不会进行任何复制操作)。数组不仅有transpose方法,还有一个特殊的T属性:
在进行矩阵计算时,经常需要用到该操作,比如利用np.dot计算矩阵内积:
对于高维数组,transpose需要得到一个由轴编号组成的元组才能对这些轴进行转置
这里第一个轴换成第二个,第二个换成第三个,第三个换成第一个
ndarray还有一个swapaxes方法,它需要接受一对轴编号:
通用函数:快速的元素级数组函数
利用数组进行数据分析
将条件逻辑表述为数组运算(where)
numpy.where函数是三元表达式x if condition else y的矢量化版本。假设我们有一个布尔数组和两个值数组:
假设我们想要根据cond中的值选取xarr和yarr的值:当cond中的值为True时,选取xarr的值,否则从yarr中选取。列表推导式的写法应该如下所示:
这有几个问题。第一,它对大数组的处理速度不是很快(因为所有工作都是由纯Python完成的)。第二,无法用于多维数组。若使用np.where,则可以将该功能写得非常简洁:
使用np.where,可以将标量和数组结合起来。例如,我可用常数2替换arr中所有正的值:
数学统计方法
用于布尔型数组的方法
排序
跟Python内置的列表类型一样,NumPy数组也可以通过sort方法就地排序:
多维数组可以在任何一个轴向上进行排序,只需将轴编号传给sort即可:
计算数组分位数最简单的办法是对其进行排序,然后选取特定位置的值:
唯一化以及其它的集合逻辑
用于数组的文件输入输出
np.save和np.load是读写磁盘数组数据的两个主要函数。默认情况下,数组是以未压缩的原始二进制格式保存在扩展名为.npy的文件中的:
如果文件路径末尾没有扩展名.npy,则该扩展名会被自动加上。然后就可以通过np.load读取磁盘上的数组:
通过np.savez可以将多个数组保存到一个未压缩文件中,将数组以关键字参数的形式传入即可:
线性代数
x.dot(y)等价于np.dot(x, y):
伪随机数生成
numpy.random模块对Python内置的random进行了补充,增加了一些用于高效生成多种概率分布的样本值的函数。例如,你可以用normal来得到一个标准正态分布的4×4样本数组:
我们说这些都是伪随机数,是因为它们都是通过算法基于随机数生成器种子,在确定性的条件下生成的。你可以用NumPy的np.random.seed更改随机数生成种子: