2.1 多维数组对象
标准Python不支持多维数组,为此NumPy库提供了支持丰富数据表示方式的多维数组ndarray,方便一维、二维甚至多维的数组处理。ndarray数组对象所有元素类型必须相同,且大小固定,在创建时定义,使用过程中不可改变。一般采用如下方式导入NumPy库。
由于NumPy库的函数较多且与其他第三方库重名,为了避免函数命名冲突,使用import…as关键字将Numpy重命名为np,在后续使用Numpy时用np代替,这样,既简化了拼写也避免与其他库的函数冲突。
案例2-1:学生课程考试成绩数据
5位学生参加了学业水平考试,考试科目共7门,考试成绩如表2-1所示。
表2-1 学业水平测试成绩表
本章将围绕此数据案例介绍如何使用ndarray存储及处理学生成绩数据。
2.1.1 一维数组对象
NumPy库的array函数可以基于Python的列表创建ndarray对象,如果列表的各个元素均为单变量,创建的就是一维ndarray对象。
【例2-1】 创建一维数组分别保存学生姓名和考试科目,访问数组元素。
NumPy库为ndarray对象提供了很多属性和方法,用于查看ndarray对象的属性,获取数据子集,并进行计算。
1.查看数组的属性
2.单个数组元素访问
访问一维ndarray的数据元素与访问Python序列的方式相同,索引序号范围为[0, n-1]或[-n, -1](n为数组大小)。
3.数组切片(slicing)
抽取数组的一部分元素生成新数组称为切片操作。切片根据给出的索引,抽取出对应的元素。
当使用索引列表进行切片操作时,外层的方括号表示数组索引操作,内层的方括号表示多个索引组成的列表。
索引也可以通过start:end:step形式给出,它生成一个等差数列,元素从start开始,end-1结束,step为步长。start默认为从头开始,end默认为最后一个元素结束,step默认步长为1。
4.根据条件筛选数组元素
ndarray可以使用条件表达式和关系运算符来选择所需要的数据元素。如筛选出names数组中值等于“王微”或“钱易铭”的元素。
条件筛选分为两个步骤,首先利用(names=='王微')|(names=='钱易铭')条件表达式创建一个布尔型的数组,然后使用此对象对names内的元素按位置选择,值是True的选中,False的不选。分步骤实现代码如下。
2.1.2 二维数组对象
使用array函数创建二维ndarray数组对象,初始化的列表,其元素也是列表。
【例2-2】 创建二维数组scores,记录“names”中每位学生对应“subjects”各门课程的考试成绩。
创建函数array的参数列表的每个元素代表1位学生的成绩,每位学生的成绩又是由7门课程成绩组成的列表。scores数组每行表示1位学生各门课程的成绩,每列表示1门科目所有学生的成绩。
1.查看数组属性
scores是一个5行、7列的2维数组,共有35个整数类型的元素。
2.二维数组切片
二维数组切片操作的基本格式:
其中row为行序号,column为列序号,中间用“,”隔开。行、列切片的表示方式与一维数组相同。如果行或列用“:”代替,表示选中对应的所有行或列。
1)访问指定行、列的元素,给出行和列两个索引值。
注意上例中在方括号中给出行切片[1,3]和列切片[0,1],表示抽取行序号为1、列序号为0,以及行序号为3、列序号为1的元素,得到一维的ndarray数组。
2)访问部分行元素,给出行列表即可,列索引的“:”可以省略。
3)访问部分列元素,如显示所有学生数学课和英语课的成绩。
前面的行索引“:”不能省略,否则无法识别是对列切片。
4)访问部分行和列数据。
访问索引为0和3的行中,1~3列的所有元素。
如果需要抽取指定某些行中指定列的所有元素,则需要进行两层切片。
首先scores[[1,3]]得到了由scores序号1、3行组成的二维ndarray对象,再在此对象上进行切片操作,取所有行的0、1列的元素。
3.条件筛选
可以使用布尔型数组筛选访问其他数组的元素。用于筛选的布尔数组,需要具有与访问数组相同的行数或列数。如筛选“肖良英”和“方绮雯”的所有课程成绩。
行索引使用(names=='肖良英')|(names=='方绮雯')布尔数组给出,表示scores中布尔数组True对应的行被选中。列索引为冒号,表示所有的列元素都选中,也可以省略。
可以对二维数组的行、列同时使用布尔表达式筛选,如显示“肖良英”和“方绮雯”的“Math”和“Python”课程成绩,可以使用两层筛选实现。
首先在二维数组中筛选出“肖良英”和“方绮雯”的所有成绩得到一个两行的二维数组,然后在此数组上选择列满足条件表达式(subjects=='Math')|(subjects=='Python')的所有行。
2.1.3 创建多维数组的常用方法
NumPy库还提供了其他一些数组创建函数,以满足不同初始化的需求。下面列出常用的数组创建和初始化函数。
1.arange()函数
arange()函数可以根据给定的起始范围和步长,生成一个由数值序列组成的数组,规则与列表索引相同。如生成从0开始到10结束的连续整数数组。
arange()函数的3个参数可以是浮点数。
2.reshape()函数
使用reshape()函数可以将一维数组转换为指定的多维数组。如将有15个连续整数的一维数组转换为3×5的二维数组。
reshape(n,m),n表示行数,m表示列数。
3.zeros()函数和ones()函数
zeros()函数和ones()函数生成指定大小的全0和全1的数组,如分别生成3×4的全0数组和4×3的全1数组。
zeros()和ones()函数的参数都为元组(n,m),n表示行数,m表示列数。
思考与练习
1.一维数组访问。
1)在subjects数组中选择并显示序号1、2、4门课的名称,使用倒序索引选择并显示names数组中“方绮雯”。
2)选择并显示names数组从2到最后的数组元素;选择并显示subjects数组正序2~4的数组元素。
3)使用布尔条件选择并显示subjects数组中的英语和物理科目名称。
2.二维数组访问。
1)选择并显示scores数组的1、4行。
2)选择并显示scores数组中行序2、4学生的数学和Python成绩。
3)选择并显示scores数组中所有学生的数学和艺术课程成绩。
4)选择并显示scores数组中“王微”和“刘旭阳”的英语和艺术课程成绩。
3.生成由整数10~19组成的2×5的二维数组。