
5.1.3 创建数组的方法
1.用array()或asarray()函数创建数组
可以用多种方式来定义数组,最常用的是用array()函数或asarray()函数。array()函数的格式如下所示:
array(object,dtype=None,copy=True,order='K',subok=False,ndmin=0)
各项参数的意义如下所示。
- object是数组的数据源,例如列表、元组、range()函数等数据序列,还可以是数组。
- dtype用于指定数据类型,如果未给出,则类型由满足保存数据所需的最小内存空间的存储类型决定。
- copy设置新建数组是否是原数组的副本还是引用。当object是数组,且object的数据类型与新建数组的数据类型相同,在copy=True时,新建的数组是原数组的副本,这时新建的数组与原数组没有任何联系,改变新建数组或原数组的元素值,不会改变另一个数组的值;在copy=False时,新建数组和原数组共用内存,改变新建数组或原数组的元素值,会改变另一个的值。
- 当object是数组时,subok用于指定新建数组是否是object数组的子类。
- order用于指定数据元素在内存中的排列形式,可以取'K'(keep)、'A'(any)、'C'(C语言风格)或'F'(Fortran语言风格),'K'和'A'用于object是数组的情况。在object不是数组时,order='F'表示新建数组按照Fortran格式排列(列排列),order='C'表示新建数组按照C格式排列(行排列),如果没有设置order,默认order='C';在object是数组时,无论copy的取值是什么,order='F'表示新建数组按照Fortran格式排列,order='C'表示新建数组按照C格式排列。在object是数组且copy= 'False'时,order='K'或'A'表示新建数组与原数组的排列形式相同;在object是数组且copy='True'时,order='K'表示原数组如果是Fortran或C排列则新建数组也是Fortran或C排列,其他情况采用最接近的方式排列,order='A'表示如果原数组是Fortran排列,则新数组是Fortran排列,其他情况是C排列。
- ndmin是可选参数,类型为int型,指定新建数组应具有的最小维数。
asarray()函数的格式是asarray(object,dtype=None,order=None,like=None),其中like作为参考物,取值是数组,返回的数组根据like数组来定义。array()和asarray()都可以将序列转化为ndarray对象,区别是当参数object不是数组时,两个函数结果相同;当object是数组且新建数组与原数组的数据类型相同时,array()在copy=True时会新建一个ndarray对象,作为原数组的副本,但是asarray()不会新建数组,而是与object共享同一个内存,改变其中一个数组的元素值,也会同时改变另一个数组的元素值,此时asarray (object)相当于array(object,copy=False)。
下面的代码可以对比在类型相同或不同,copy=False时的差异,以及类型相同,copy= True时的差异。

2.用arange()函数创建数组
与Python的内置函数range()类似,NumPy的arange()函数可以产生一系列数据,并生成一维数组。arange()函数的格式如下:
arange([start,]stop[,step],dtype=None,like=None)
其中,start是起始值,stop是终止值,step是步长。arange()函数创建的数组包含起始值,但不包含终止值,start、stop和step可以取整数、浮点数和复数。start和step是可选参数,如果忽略,则start默认为0,step默认为1。
下面是用arange()函数创建数组的一些实例。

3.用linspace()等函数创建数组
NumPy的linspace()函数可以在起始值和终止值之间线性取值,并返回新生成的数组。linspace()函数的格式如下:
linspace(start,stop,num=50,endpoint=True,retstep=False,dtype=None,axis=0)
其中,start和stop是起始值和终止值,取值可以是标量或数组、列表或元组;num是返回的数组中元素的个数,包括start;如果endpoint=True,则数组的最后一个元素是stop值,如果endpoint=False,则返回的数组不包括stop;如果retstep=True,则返回由数组和步长构成的元组;dtype指定数组的类型;axis是坐标轴,只有在start和end是数组、列表或元组时才有效。

linspace()用等差数列创建数组,与linspace()相似的函数有geomspace()和logspace()。geomspace()创建等比数列,而logspace()先生成等差数列,然后再把等差数列作为指数,计算指定基(base)的幂,返回由幂计算的数组。geomspace()和logspace()的格式如下所示:
geomspace(start,stop,num=50,endpoint=True,dtype=None,axis=0) logspace(start,stop,num=50,endpoint=True,base=10.0,dtype=None,axis=0)

4.用zeros()等函数创建数组
利用NumPy提供的zeros()、ones()、empty()、full()、eye()和identity()函数能快速创建特殊数组。zeros()创建元素值全部是0的数组;ones()创建元素值全部是1的数组;empty()创建没有初始化的数组,数值的元素值不确定;full()创建元素值全部是指定值的数组;eye()创建一个二维数组,在指定的对角线上的值为1,其他全部为0;identity()创建行和列相等,主对角线上的值全部是1、其他元素全部为0的单位矩阵。这几个函数的格式如下所示:
zeros(shape,dtype=float,order='C') ones(shape,dtype=None,order='C') empty(shape,dtype=float,order='C') full(shape,fill_value,dtype=None,order='C') eye(N,M=None,k=0,dtype=float,order='C') identity(n,dtype=None)
其中,参数shape可以取整数或由整数构成的元组,例如shape取5表示创建含有5个元素的一维数组,shape取(3,6)表示创建二维数组,第1维的元素个数是3,第2维的元素个数是6;fill_value表示元素的初始值;order设置数组元素在内存中的排列形式,可以取'C'或'F'。对于eye()返回形状是(N,M)的二维数组,其中N是行的数量,M是列的数量,如果忽略M,则M=N;k是对角线的索引,或相对于主对角线的偏移量,k=0是主对角线,k>0是上对角线,k<0是下对角线。对于identity()返回形状是(n,n)的二维数组,只在主对角线上的值为1,其他全部为0。用数组的fill(value)方法可以设置数组的所有元素的值是value。

5.用zeros_like()等函数创建数组
NumPy提供了zeros_like()、ones_like()、empty_like()和full_like()函数,这些函数返回与给定数组相同形状的数组,并进行初始化。这些函数的格式如下所示:
zeros_like(object,dtype=None,order='K',subok=True,shape=None) ones_like(object,dtype=None,order='K',subok=True,shape=None) empty_like(object,dtype=None,order='K',subok=True,shape=None) full_like(object,fill_value,dtype=None,order='K',subok=True,shape=None)
其中,object表示数组、列表或元组等;如果没有指定shape,则创建的数组的形状与a的形状相同,如果重新指定shape的值,则创建的数组的形状是shape指定的形状;order可以取'C'、'F'、'A'或'K'。

6.用fromfunction()函数创建数组
fromfunction()函数用指定形状的数组的下标(行、列索引值)作为实参,传递给指定的函数,通常用于绘制图形。fromfunction()函数的格式如下,其中function是可以调用的函数名;shape指定数组的形状,数组的下标将会传递给函数。
fromfunction(function,shape,dtype=float,**kwargs)

7.用fromfile()方法创建数组
NumPy的fromfile()函数可从文本文件或二进制文件中直接读取数据,返回数组。fromfile()函数的格式如下所示:
fromfile(file,dtype=float,count=-1,sep='',offset=0)
其中,file是路径和文件名;count表示读取的数据的数量,-1表示读取所有数据;如果文件是文本文件,sep是数据之间的分割符,空格符('')可以匹配0和多个空格符,sep是空符(")表示文件是二进制文件;offset是二进制文件中相对当前位置的偏移量(字节)。fromfile()函数的返回值是一维数组,可以用数组的reshape()方法重新调整数组的形状。
下面的代码是从data.txt文件中读取数据创建数组,data.txt文件中有两行数据,分别是1.1 2.3 4.5和2.3 4.2 7.8,数据之间用空格隔开,读取数据后用数组的reshape()方法重新调整数组的形状。

用数组的tofile(fid, sep='', format="%s")方法可以将数组保存到文件中,fid是路径和文件名。
8.用fromiter()方法创建数组
NumPy的fromiter()函数可以从一个迭代序列中创建一维数组,其格式如下所示:
fromiter(iterable,dtype,count=-1)
其中,iterable是迭代序列;count是读取的数据数量,默认是-1,表示读取所有数据。

9.用fromstring()方法创建数组
用NumPy的fromstring()方法可以从文本中创建一维数组。fromstring()方法的格式如下所示:
fromstring(string,dtype=float,count=-1,sep='')
其中,string是包含数据的字符串;dtype指定数组的类型;count指定读取数据的数量,默认是-1,表示读取string中的所有数据;sep指定string中数据之间的分割符。

10.网格数组
在用Matplolib绘制图像时,经常会绘制如z=f(x,y)函数的图像,即z是x和y的函数,这时,x和y都需要取一些离散值,例如x=1,2,3,4,y=2.5,3.5,4.5,这样x和y将形成12个点P11~P43,如图5-2所示。

图5-2 网格点
要写出这12个点的坐标,可以用下面的两个矩阵X和Y分别表示这12个点的x和y坐标构成的矩阵,用X和Y对应位置上的数据即可写出Pij点的坐标。

NumPy提供了由坐标向量换算成坐标矩阵的函数meshgrid(),它可以生成指定维数的坐标矩阵。meshgrid()函数的格式如下所示:
meshgrid(x1,x2,...,xn,copy=True,sparse=False,indexing='xy')
其中,xi表示一维数组、列表或元组,xi的数量决定了meshgrid()函数返回值的维数;copy=False时返回值是对原始xi的引用,这样可以节省内存;sparse=True时,返回值是稀疏矩阵,这样也可以节省内存;indexing可以取'xy'或'ij','xy'表示返回值是直角坐标矩阵,'ij'表示返回值是坐标矩阵的转置矩阵。
除了用meshgrid()函数创建网格坐标矩阵外,还可以用mgrid()函数来创建多维坐标矩阵。mgrid()函数的格式是mgrid[start:stop:step,start:stop:step,...],每维的取值范围由start:stop:step来定义,如果step是实数,则不包含stop,step表示步长;如果step是复数,则包含stop,step幅值的整数部分是数据点的个数。
