NumPy(Numerical Python的简称)是Python数值计算最重要的基础包。
NumPy的部分功能如下:
对于大部分数据分析应用而言,我最关注的功能主要集中在:
NumPy之于数值计算特别重要的原因之一,是因为它可以高效处理大数组的数据。这是因为:
基于NumPy的算法要比纯Python快10到100倍(甚至更快),并且使用的内存更少。
创建数组最简单的办法就是使用array函数
嵌套序列:
可以用属性ndim和shape来查看一个数组的维度和形状:
使用dtype属性查看数据类型:
其他创建数组的方法:
dtype(数据类型)是一个特殊的对象,在使用array创建数组时我们可以通过dtype属性来设置数据类型:
数值型dtype的命名方式相同:一个类型名(如 float或int),后面跟一个用于表示各元素位长的数字。标准的双精度浮点值(即 Python中的float对象)需要占用8字节(即64位)。因此,该类型在NumPy中就记 作float64。表4-2列出了NumPy所支持的全部数据类型。
通过ndarray的astype方法明确地将一个数组从一个dtype转换成另一个dtype:
笔记:调用astype总会创建一个新的数组(一个数据的备份),即使新的dtype 与旧的dtype相同。
三、NumPy数组的运算
Numpy数组的矢量化(Vectorization):
当你将一个标量值赋值给一个切片时(如arr[5:8]=12),该值会自动传 播(也就说后面将会讲到的“广播”)到整个选区。
跟列表最重要的区别在于,数组 切片是原始数组的视图。这意味着数据不会被复制,视图上的任何修改都会直接反 映到源数组上。
由于NumPy的设计目的是处理大数据,所以你可以想 象一下,假如NumPy坚持要将数据复制来复制去的话会产生何等的性能和内存问题。
注意:如果你想要得到的是ndarray切片的一份副本而非视图,就需要明确地进行复制操作,例如 arr[5:8].copy() 。
在一个二维数组中,各索引位置上的元素不再 是标量而是一维数组:
可以传入一个以逗号隔开的索引列表来选取单个元素。也就是说,下面两种方式是等价的
图4-1说明了二维数组的索引方式。轴0作为行,轴1作为列。
在多维数组中,如果省略了后面的索引,则返回对象会是一个维度低一点的ndarray(它含有高一级维度上的所有数据)。
arr3d[0]是一个2×3数组:
这里注意,些选取数组子集都是数组的视图,所以当标量值和数组赋值给arr3d[0]这样一个数组索引子集时,原数组的数据也会发生变化。
注意,“只有冒号”表示选取整个轴。
当行索引和列索引均时切片时,只能得到一个和原数组相同维度的数组视图。
通过将证书索引和切片索引混合,可以得到低纬度的切片。
跟算术运算一样,数组的比较运算(如==)也是矢量化的。
布尔型数组可用于数组索引,此时布尔型数组的长度必须跟被索引的轴长度一致,此外,还可以将布尔型数组跟切片、整数(或整数序列,稍后将对此进行详细讲解)混合使用:
注意:如果布尔型数组的长度不对,布尔型选择就会出错,因此一定要小心。
下面的例子,我选取了 names == 'Bob' 的行,并索引了列:
要选择除"Bob"以外的其他值,既可以使用不等于符号(!=),也可以通过~对条件 进行否定:
在条件中我们还能使用&(和)、|(或)来进行逻辑条件的组合
注意:Python关键字and和or在布尔型数组中无效。要使用&与|。
通过布尔型索引选取数组中的数据,将总是创建数据的副本,即使返回一模一样的 数组也是如此。
通过布尔型数组设置值是一种经常用到的手段。例如,将data中的所有负值都设置为 0,我们只需:
通过一维布尔数组设置整行或列的值也很简单:
花式索引(Fancy indexing)是一个NumPy术语,它指的是利用整数数组进行索 引。
无论数组是多少维的,花式索引总是 一维的。
记住,花式索引跟切片不一样,它总是将数据复制到新数组中。
假设我们有一个8×4数组:
一次传入多个索引数组会有一点特别。它返回的是一个一维数组,其中的元素对应 各个索引元组:
这个花式索引的行为可能会跟某些用户的预期不一样(包括我在内),选取矩阵的 行列子集应该是矩形区域的形式才对。下面是得到该结果的一个办法:
转置是重塑的一种特殊形式,它返回的是源数据的视图(不会进行任何复制操作)。
数组不仅有transpose方法,还有一个特殊的T属性都可以实现数组的转置。
对于高纬度数组,transpose需要得到一个由轴编号组成的元组才能对这些轴进行转置:
这里,第一个轴被换成了第二个,第二个轴被换成了第一个,最后一个轴不变。