Python提供了一个array模块。array 和list 不同,它直接保存数值,和C语言的一维数组比较类似。但是由于Python的array模块不支持多维,也没有各种运算函数,因此也不适合做数值运算。NumPy的诞生弥补了这些不足。NumPy提供了一种存储单一数据类型的多维数组–ndarray。
感受一下NumPy如何使用类似于Python内建对象的标量计算语法进行批量计算,首先导入NumPy,再生成一个小的随机数组:
然后给data加上一个数学操作:
在第一个数学操作中,所有的元素都同时乘以了10。在第二个数学操作中,数组中的对应元素进行了相加。
注意:使用标准的NumPy导入方式import numpy as np。也可以在代码中写from numpy import *来省略多写的一个np.,然而建议写标准导入的方式。numpy这个命名空间包含了大量与Python内建函数重名的函数(比如min和max)。
生成数组最简单的方式就是使用array函数。array函数接收任意的序列型对象(当然也包括其他的数组),生成一个新的包含传递数据的NumPy数组。例如,列表的转换就是一个好例子:
嵌套序列,例如同等长度的列表,将会自动转换成多维数组:
因为data2是一个包含列表的列表,所以Numpy数组arr2形成了二维数组。可以通过检查ndim和shape属性来确认这一点:
除非显式地指定,否则np.array会自动推断生成数组的数据类型。数据类型被存储在一个特殊的元数据dtype中。例如,之前的两个例子:
除了np.array,还有很多其他函数可以创建新数组。例如,给定长度及形状后,zeros可以一次性创造全0数组,ones可以一次性创造全1数组。empty则可以创建一个没有初始化数值的数组。想要创建高维数组,则需要为shape传递一个元组:
arange是Python内建函数range的数组版:
数据类型,即dytpe,是一个特殊的对象,它包含了ndarray需要为某一种类型数据所申明的内存块信息(也称为元数据,即表示数据的数据):
dtype是NumPy能够与其他系统数据灵活交互的原因。数据的dtype通常都是按照一个方式命名:类型名,比如float和int,后面再接上表明每个元素位数的数字。一个标准的双精度浮点值(Python中数据类型为float),将使用8字节或64位。因此,这个类型在NumPy中称为float64。
数组之所以重要是因为它允许你进行批量操作而无须任何for循环。NumPy用户称这种特性为向量化。任何在两个等尺寸数组之间的算术操作都应用了逐元素操作的方式:
带有标量计算的算术操作,会把计算参数传递给数组的每一个元素:
同尺寸数组之间的比较,会产生一个布尔值数组:
NumPy数组索引是一个大话题,有很多种方式可以让你选中数据的子集或某个单个元素。一维数组比较简单,看起来和Python的列表很类似:
如果传入一个数值给数组的切片,例如arr[5:8] = 12,数值被传递给了整个切片。区别于Python的内建列表,数组的切片是原数组的视图。这意味着数据并不是被复制了,任何对于视图的修改都会反映到原数组上。
如果想要一份数组切片的拷贝而不是一份视图的话,就必须显式地复制这个数组,例如arr[5:8].copy()
对更高维度的数组,会有更多选择。在一个二维数组中,每个索引值对应的元素不再是一个值,而是一个一维数组:
因此,单个元素可以通过递归的方式获得。可以通过传递一个索引的逗号分隔列表去选择单个元素,以下两种方式效果一样:
展示二维数组上的索引,将0轴看作“行”,将1轴看作“列”。
在多维数组中,可以省略后续索引值,返回的对象将是降低一个维度的数组。因此在一个2×2×3的数组arr3d中:
arr3d[0]是一个2×3的数组:
类似地,arr3d[1, 0]返回的是一个一维数组:
需要注意的是,以上的数组子集选择中,返回的数组都是视图。
与Python列表的一维对象类似,数组可以通过类似的语法进行切片:
前面的二维数组,arr2d,对数组进行切片略有不同:
数组沿着轴0进行了切片。表达式arrzd[:2]的含义为选择arr2d的前两“行”。
对切片表达式赋值时,整个切片都会重新赋值:
假设我们的数据都在数组中,并且数组中的数据是一些存在重复的人名。使用numpy.random中的randn函数来生成一些随机正态分布的数据:
假设每个人名都和data数组中的一行相对应,并且我们想要选中所有’Bob’对应的行。与数学操作类似,数组的比较操作(比如==)也是可以向量化的。因此,比较names数组和字符串’Bob’会产生一个布尔值数组:
在索引数组时可以传入布尔值数组:
为了选择除了’Bob’以外的其他数据,可以使用!=或在条件表达式前使用~对条件取反:
当要选择三个名字中的两个时,可以对多个布尔值条件进行联合,需要使用数学操作符如&(and)和|(or):
使用布尔值索引选择数据时,总是生成数据的拷贝,即使返回的数组并没有任何变化。
注意:Python的关键字and和or对布尔值数组并没有用,使用&(and)和|(or)来代替。
神奇索引是NumPy中的术语,用于描述使用整数数组进行数据索引。
假设有一个8×4的数组:
为了选出一个符合特定顺序的子集,可以简单地通过传递一个包含指明所需顺序的列表或数组来完成:
如果使用负的索引,将从尾部进行选择:
传递多个索引数组时情况有些许不同,这样会根据每个索引元组对应的元素选出一个一维数组:
即第1行第0列的元素是4,第5行第3列的元素是23,依此类推。
转置是一种特殊的数据重组形式,可以返回底层数据的视图而不需要复制任何内容。数组拥有transpose方法,也有特殊的T属性:
当进行矩阵计算时,可能会经常进行一些特定操作,比如,当计算矩阵内积会使用np.dot:
评论区(2)
非常好
非常好