
4.1 数组的创建与操作
通过numpy模块中的array函数实现数组的创建,如果向函数中传入一个列表或元组,将构造简单的一维数组;如果传入多个嵌套的列表或元组,则可以构造一个二维数组。构成数组的元素都是同质的,即数组中的每一个值都具有相同的数据类型,下面分别构造一个一维数组和二维数组。
4.1.1 数组的创建

如上结果所示,可以将列表或元组转换为一个数组,在第二个数组中,输入的元素含有整数型和浮点型两种数据类型,但输出的数组元素全都是浮点型(原来的整型会被强制转换为浮点型,从而保证数组元素的同质性)。
使用位置索引可以实现数组元素的获取,虽然在列表中讲解过如何通过正向单索引、负向单索引、切片索引和无限索引获取元素,但都无法完成不规律元素的获取,如果把列表转换为数组,这个问题就可以解决了,下面介绍具体的操作。
4.1.2 数组元素的获取
先来看一下一维数组元素与二维数组元素获取的例子,代码如下:

如上结果是通过位置索引获取一维和二维数组中的元素,在一维数组中,列表的所有索引方法都可以使用在数组上,而且还可以将任意位置的索引组装为列表,用作对应元素的获取;在二维数组中,位置索引必须写成[rows,cols]的形式,方括号的前半部分用于控制二维数组的行索引,后半部分用于控制数组的列索引。如果需要获取所有的行或列元素,那么,对应的行索引或列索引需要用英文状态的冒号表示。但是,要是从数组中取出某几行和某几列,通过[rows,cols]的索引方法就不太有效了,例如:

如上结果所示,第一个打印结果并不是2×2的数组,而是含两个元素的一维数组,这是因为numpy将[[0,-1],[1,3]]组合的理解为了[0,1]和[-1,3];同样,在第二个元素索引中,numpy仍然将[[0,-1],[1,2,3]]组合理解为拆分单独的[rows,cols]形式,最终导致结果中的错误信息。实际上,numpy的理解是错误的,第二个输出应该是一个2×3的数组。为了克服[rows,cols]索引方法的弊端,建议读者使用ix_函数,具体操作如下:

4.1.3 数组的常用属性
如果不是手工写入的数组,而是从外部读入的数据,此时也许对数据就是一无所知,如该数据的维数、行列数、数据类型等信息,下面通过简短的代码来了解数组的几个常用属性,进而跨出了解数据的第一步。
在numpy模块中,可以通过genfromtxt函数读取外部文本文件的数据,这里的文本文件主要为csv文件和txt文件。关于该函数的语法和重要参数含义如下:
np.genfromtxt(fname, dtype=<class ‘float’>, comments=’#’, delimiter=None, skip_header=0, skip_footer=0, converters=None, missing_values=None, filling_values=None, usecols=None, names=None,)
- fname:指定需要读入数据的文件路径。
- dtype:指定读入数据的数据类型,默认为浮点型,如果原数据集中含有字符型数据,必须指定数据类型为“str”。
- comments:指定注释符,默认为“#”,如果原数据的行首有“#”,将忽略这些行的读入。
- delimiter:指定数据集的列分割符。
- skip_header:是否跳过数据集的首行,默认不跳过。
- skip_footer:是否跳过数据集的脚注,默认不跳过。
- converters:将指定列的数据转换成其他数值。
- miss_values:指定缺失值的标记,如果原数据集含指定的标记,读入后这样的数据就为缺失值。
- filling_values:指定缺失值的填充值。
- usecols:指定需要读入哪些列。
- names:为读入数据的列设置列名称。
接下来通过上面介绍的数据读入函数,读取学生成绩表数据,然后使用数组的几个属性,进一步掌握数据的结构情况。

如上结果所示,读入的学生成绩表是一个二维的数组(type函数和ndim方法),一共包含1380行观测和5个变量(shape方法),形成6900个元素(size方法),并且这些元素都属于浮点型(dtype方法)。通过上面的几个数组属性,就可以大致了解数组的规模。
4.1.4 数组的形状处理
数组形状处理的手段主要有reshape、resize、ravel、flatten、vstack、hstack、row_stack和colum_stack,下面通过简单的案例来解释这些“方法”或函数的区别。

如上结果所示,虽然reshape和resize都是用来改变数组形状的“方法”,但是reshape方法只是返回改变形状后的预览,但并未真正改变数组arr3的形状;而resize方法则不会返回预览,而是会直接改变数组arr3的形状,从前后两次打印的arr3形状就可以发现两者的区别。如果需要将多维数组降为一维数组,利用ravel、flatten和reshape三种方法均可以轻松解决:

如上结果所示,在默认情况下,优先按照数组的行顺序,逐个将元素降至一维(见数组降维的前三行打印结果);如果按原始数组的列顺序,将数组降为一维的话,需要设置order参数为“F”(见数组降维的后三行打印结果)。尽管这三者的功能一致,但之间是否存在差异呢?接下来对降维后的数组进行元素修改,看是否会影响到原数组arr4的变化:

如上结果所示,通过flatten方法实现的降维返回的是复制,因为对降维后的元素做修改,并没有影响到原数组arr4的结果;相反,ravel方法与reshape方法返回的则是视图,通过对视图的改变,是会影响到原数组arr4的。
vstack用于垂直方向(纵向)的数组堆叠,其功能与row_stack函数一致,而hstack则用于水平方向(横向)的数组合并,其功能与colum_stack函数一致,下面通过具体的例子对这四种函数的用法和差异加以说明。

如上结果所示,前两个输出是纵向堆叠的效果,后两个则是横向合并的效果。如果是多个数组的纵向堆叠,必须保证每个数组的列数相同;如果将多个数组按横向合并的话,则必须保证每个数组的行数相同。