0x01:
基础篇:
numpy的主要对象是同种元素的多维数组。这是一个所有元素都是一种类型、通过一个正整数元组索引的元素表格(通常是元素是数字)。在NumPy中维度(dimensions)叫做轴(axes),轴的个数叫做秩(rank)。
Numpy的数组类被称为ndarray.通常被称为数组。注意numpy.array和标准Python库类aray.array并不相同,后者只处理一维数组和提供少量功能。更多的重要ndarray对象属性有如下:
ndarray.ndim 数组轴的个数,轴的个数被称为秩
ndarray.shape 数组的维度。这是一个指示数组在每个维度上大小的整数元组
ndarray.size 数组元素的个数,等于shape属性中元组元素的乘积
ndarray.dtype 一个用来描述数组中元素类型的对象,可以通过创造或者指定dtype使用标准Python类型
ndarray.itemsize 数组中每个元素的字节大小。例如,一个元素类型为float64的数组itemsiz属性值为8(=64/8),又如,一个元素类型为complex32的数组item属性为4(=32/8)
ndarray.data 包含实际数组元素的缓冲区,通常我么不需要使用这个属性
实例如下:
创建数组
创建数组的方法有好几种,我们可以使用array函数从常规的Python列表和元组构造数组。所创建的数组类型由原序列的元素推导而来,如我们创建一个一维数组
当然我们也可以使用数组将序列包含序列转化为二维的数组,序列包含序列包含序列转化为三维数组,同时可以直接在创建时候指定显示类型
一般来说,数组的元素开始都是未知的,但是他的大小是已知的。因此,numpy提供了一些可以使用占位符来创建数组的函数。这样的话能够最小化扩展数组的需求和高昂的代价,如一下几种函数
函数function()创建一个全是0的数组,函数ones创建一个全为1的数组,函数empty创建一个内容随机并且依赖与内存状态的数组。当然默认数组的类型都是float64.
为了创建一个数列,numpy提供一个类似arange的函数返回数组而不是列表
当arange
使用浮点数参数时,由于有限的浮点数精度,通常无法预测获得的元素个数。因此,最好使用函数linspace
去接收我们想要的元素个数来代替用range来指定步长。
其它函数array, zeros, zeros_like, ones, ones_like, empty, empty_like, arange, linspace, rand, randn, fromfunction, fromfile参考:NumPy示例
打印数组
当你打印一个数组,numpy以类似嵌套列表的形式显示它,但是呈以下布局。
最后的轴从左到右打印
次后的轴从顶向下打印
剩下的轴从顶向下打印,每个切片通过一个空行与下一个隔开。
一维数组被打印成行,二维数组被打印成矩阵,三维数组被打印成矩阵列表。
基本运算
数组的算术运算都是按元素的,的数组被创建并且被结果填充。
不像许多矩阵语言,numpy的乘法运算符号可以使用dot函数或者创建矩阵对象实现
有些操作符号像+=和*=被用来更改已经存在的数组而不创建一个新的数组
这些运算默认应用到数组好像他就是一个数字组成的列表,无关数组的形状。然而,指定axis参数你可以把运算应用到指定的数轴上:
通用函数(ufunc)
NumPy提供常见的数学函数如sin,cos,exp在NumPy中,这些叫作“通用函数”(ufunc)。在NumPy里这些函数作用按数组的元素运算,产生一个数组作为输出。
索引,切片和迭代
一维的数组可以被索引,切片和迭代,就像其他列表和python序列一样。
多维数组的话可以每个轴有一个索引。这些索引由一个逗号分割的元组给出。
当少于轴数的索引被提供时候,缺失的索引被认为是整个切片
比如b[-1]=b[-1,:]
b[i]中的括号中的表达式被当作i和一系列的:,来代表剩下的轴。numpy也允许你使用点,如b[i,...]
点(..)代表许多产生一个完整的索引元组必要的分号。如果x是秩为5的数组,那么
x[1,2,...]==x[1,2,:,:,:]
x[.....,3]==x[:,:,:,:,3]
x[4,...,5]==x[4,:,:,:,5]
迭代多维数组就是相对于第一个轴而言的,然而如果你想对每个数组进行运算,我们可以使用flat属性,该属性是数组元素的一个迭代器。
形状操作
更改数组的形状
一个数组的形状由他的每个轴上的元素的个数给出,也就是a.shape(a代表一个数组)
一个数组的形状可以被多种命令修改
如ravel(),transpose(),reshape(),resize()等等
组合不同的数组
几种方法可以沿着不同轴将数组堆叠在一起:
column_stack以列将一维数组组合成二维数组,他等价于vstack对一维数组
rows_stack函数,将一维数组以行的形式组合成二维数组
对于那些维度比较高的数组,hstack沿着第二个轴组合,vstack沿着第一个轴组合,concatenate允许可选参数组合时候沿着的轴,在复杂的情况下,r_[]和c_[]对创建沿着一个方向组合的数很有用,他们允许范围符号(":")
vsplit沿着纵向的轴分割,array split允许指定沿着哪个轴分割。
复制和视图
当运算或者处理数组的时候,它们的数据有时被拷贝到新的数组有时不是。这通常是新手的困惑之源。以下介绍三种情况:
完全不拷贝
简单的赋值不拷贝数组对象或者它们的数据。
python传递不定对象作为参考,所以函数调用的话不会拷贝数组。
视图(view)和浅复制
不同的数组对象分享一个数据。视图方法创造一个新的数组指向同一数据。
切片数组返回它的一个视图。
深复制方法(copy())
这种复制方法的话完全复制数组和他的数据。
函数和方法(method)总览
这是个numpy函数和方法分类排列目录。这些名字链接到numpy示例,你可以看到这些函数在起作用
创建数组函数:
arange, array, copy, empty, empty_like, eye, fromfile, fromfunction, identity, linspace, logspace, mgrid, ogrid, ones, ones_like, r , zeros, zeros_like
转化:
astype, atleast 1d, atleast 2d, atleast 3d, mat
操作:
array split, column stack, concatenate, diagonal, dsplit, dstack, hsplit, hstack, item, newaxis, ravel, repeat, reshape, resize, squeeze, swapaxes, take, transpose, vsplit, vstack
询问:
all, any, nonzero, where
排序:
argmax, argmin, argsort, max, min, ptp, searchsorted, sort
运算:
choose, compress, cumprod, cumsum, inner, fill, imag, prod, put, putmask, real, sum
基本统计:
cov, mean, std, var
基本线性代数:
cross, dot, outer, svd, vdot
进阶:
广播法则:
广播法则能够使通用函数能够有意义得处理不具有相同形状的输入/
广播第一法则是:如果所有的输入数组的为敌不都相同,一个"1"将被重复地添加在维度较小的数组上直至所有的数组拥有一样的维度。
广播第二法则确定长度为1的数组沿着特殊的方向表现地好像它有沿着那个方向最大形状的大小,对于数组来说,沿着那个维度的数组元素的值理应相同。
应用广播法则之后,所有的数组的大小必须匹配。
花哨的索引和索引技巧
numpy比普通python序列提供更多的索引功能,除了索引整数和切片,正如我们之前看到的,数组可以被整数数组和布尔数组索引。
通过数组索引:
当被索引的数组a是多维的时候,每一个唯一的索引数列指向a的第一维。以下示例通过将图片标签用调色版转换成色彩图像展示了这种行为。
自然的话,我们可以把i和j放到序列中,然后通过list索引
然而,我们不能把i和j放在一个数组里面,因为这个数组将被解释成索引a的第一维。
另一个常用的数组索引用法就是搜索时间序列的最大值。
你也可以使用数组索引作为目标来赋值:
通过布尔数组索引
当我们使用整数数组索引数组时候,我们提供了一个索引列表去选择。通过布尔数组索引的方法是不同的我们显示地选择数组中我们想要和不想要的元素。
这个属性在赋值的时候非常有用:
你可以参考曼德博集合示例看看如何使用布尔索引来生成曼德博集合的图像。
注意一维数组的长度必须和你想要切片的维度或者轴的长度一致,在之前的例子中,b1是一个秩为1长度为三的数组,b2的长度为4,与a的第二秩(列)相一致。
ix_()函数
ix_()函数可以为了获得多元组的结果而用来结合不同向量。例如,如果你想要用所有的向量a,b,c元素组成的三元组来计算a+b*c
线性代数
简单数组运算
参考numpy文件夹中的linalg.py获得更多信息
矩阵类
这是一个关于矩阵类的简单介绍。
索引:比较矩阵和二维数组
注意numpy中的数组和矩阵有些重要的区别。numpy提供了两个基本的对象:一个N维数组对象和一个通用函数对象。其他对象都是建构在他们之上的。
特别的,矩阵是继承自NumPy数组对象的二维数组对象。对数组和矩阵,索引都必须包含合适的一个或多个这些组合:整数标量、省略号 (ellipses)、整数列表;布尔值,整数或布尔值构成的元组,和一个一维整数或布尔值数组。矩阵可以被用作矩阵的索引,但是通常需要数组、列表或者 其它形式来完成这个任务。
像平常在Python中一样,索引是从0开始的。传统上我们用矩形的行和列表示一个二维数组或矩阵,其中沿着0轴的方向被穿过的称作行,沿着1轴的方向被穿过的是列。
区别:
对二维数组使用一个冒号产生一个一维数组,然而矩阵产生了一个二维矩阵。例如,一个M[2,:]切片产生了一个形状为(1,4)的矩阵,相比之下,一个数组的切片总是产生一个最低可能维度的数组。例如,如果C是一个三维数组,C[.....,1]产生了一个二维数组而C[1,:,1]产生了一个一维数组。从这开始,如果相应的矩阵切片结果是相同的话,我们将只展示数组切片的结果。
假如我们想要一个数组的第一列和第三列,一种方法是使用列表切片
比如A[:,[1,3]]
稍微复杂点的方法是使用take()方法(method)
A[:,].take([1,3],axis=1)
如果想跳过第一行,我们可以这样:
A[1:,].take([1,3],axis=1)
或者我们仅仅使用A[ix_((1,2),(1,3))]
或者我们使用A[1:[1,3]].还有另外一种方法是通过矩阵向量积
A[ix_((1,2),(1,3))]
现在的话让我们做些复杂的。比如说我们想要保留第一行大于的列。另外一种方法是创建布尔索引。
A[0,:]>1
A[:,A[0,;]>1]
这个过程的问题是用“矩阵切片”来切片产生一个矩阵12,但是矩阵有个方便的A
属性,它的值是数组呈现的。所以我们仅仅做以下替代:
如果我们想要在矩阵两个方向有条件地切片,我们必须稍微调整策略,代之以:
我们需要使用向量积ix_:
技巧和提示:
自动改变形状
更改数组的维度,你可以省略一个尺寸,它将自动推导出来。
向量组合
我们如何用两个相同的行向量列表构建一个二维数组?在MATLAB中这样非常简单:如果x和y是两个相同长度的向量,你仅仅需要做m=[x;y].在numpy中这个过程函数column_stack,dstack,hstack和vstack来完成,取决于你想要在那个维度上组合。
直方图
numpy中histogram函数应用到一个数组返回一堆向量;直方图数组和箱式向量。注意:matplotlib也有一个用来建立直方图的函数(叫做hist,正如matlab中一样)与numpy中的不同。主要差别是pylab.hist自动绘制直方图,而numpy.histogram仅仅产生数据。