访问数组的单个元素和多个元素都需要通过索引来进行,使用数组索引需要遵循一定的语法规则。本课重点介绍了数组的切片、花式索引、布尔索引和where函数。
访问数组的元素可以通过数组的索引来进行,通过索引可以访问数组的单个元素,也可以访问数组的多个元素,当访问数组的多个元素时,也称为对数组的切片,被切片的元素在数组中不一定连续。
数组单个元素的访问
例1 访问数组的单个元素
# 导入numpy库
import numpy as np
# 定义a、b、c数组
a = np.array([10,11,12,16,30,31])
b = np.array([[1.0,2.0,3.0],[3.0,4.0,5.0]])
c=np.array([[[11,2,21,33],[100,0.98,0.01,100.12]], [[0.1,0.9,0.178,0.03],[1.26,1.89,1.09,3.21]]])
# a是一维数组(与列表相同)
print(a.shape)
# b是二维数组(矩阵)
print(b.shape)
# c是三维数组(立体世界)
print(c.shape)
# 输出数组a第3个元素(只有一个维度)
print("数组a第3个元素:%d" % (a[2]))
# 输出数组b第2行第1个元素(有两个维度,为行和列)
print("数组b第2行第1个元素:%.2f" % (b[1][0]))
# 输出数组b第1行第0个元素
print("数组b第1第1个元素:%.2f" % (b[0][0]))
# 输出数组c值为1.26的元素
print("数组c值为1.26的元素:%.2f" % (c[1][1][0]))
对数组元素的访问是通过元素所在数组位置的索引进行的:在一维数组中,数组的索引是由一个数字构成的,通过这一个数字组成的索引,对一维数组的元素进行访问;在二维数组中,数组的索引是由两个数字构成的,通过这两个数字组成的索引,对二维数组的元素进行访问;在三维数组中,数组的索引是由三个数字构成的,通过这三个数字组成的索引,对三维数组的元素进行访问。依次类推,多维数组的元素访问是通过与维数相同的索引来访问的。
数组的切片
数组的切片是访问数组的多个元素,被切片的元素在数组中不一定连续,它们被放置到一个新的数组内。
一维数组的切片
一维数组的切片和列表的切片相同,遵循列表的切片语法。
例2 一维数组的切片
# 导入numpy库
import numpy as np
# 定义一维数组a
a = np.array([10,11,12,16,30,31,101,102,103])
# 访问数组a起始索引为1,终止索引为7的元素(不含终止索引)
b = a[1:7]
print(b)
# 访问数组a起始索引为0,终止索引为6的元素
b = a[:6]
print(b)
# 访问数组a起始索引为3,终止索引为数组长度的元素(包含终止索引)
b = a[3:]
print(b)
# 访问数组a起始索引为1,终止索引为7,步长为2的元素(不含终止索引)
b = a[1:7:2]
print(b)
二维数组的切片
二维数组可以表示矩阵,是非常重要的一类数组,也称为行列结构。二维数组的切片比一维数组的切片要复杂一些。切片语法类似一维数组的语法,不同点是起始索引为行切片,终止索引为列切片。
a = np.array([[10,11,12,18,20],
[22,32,62,82,102],
[36,39,29,27,21],
[79,75,71,70,73],
[91,92,93,94,95]
])
a[0,1:4] 返回一维数组:
[11 12 18]
其中起始索引0为数组a的第1行,终止索引1:4表示取列索引从1到4的元素(不包含4)。
a [1:4,0] 返回一维数组:
[22 36 79]
其中起始索引为数组a的1至4行(不包含第4行),终止索引0表示取第0列的元素。
a[0:5:2,0:5:2] 返回二维数组
[[10 12 20]
[36 29 21]
[91 93 95]]
其中起始索引从0行到4行,行的步长为2,终止索引从0列到4列,列的步长为2。
因为是取全部的行和例,a[0:5:2,0:5:2]也可以写成a[::2,::2]。
a[:,1] 返回一维数组
[11 32 39 75 92]
其中起始索引从0到4行,单独使用“:”表示选择所有的行,终止索引为第2列。
例3 二维数组的切片
# 导入numpy库
import numpy as np
# 定义二维数组a
a = np.array([[10,11,12,18,20],
[22,32,62,82,102],
[36,39,29,27,21],
[79,75,71,70,73],
[91,92,93,94,95]
])
# 选取数组元素
b = a[0,1:4]
print(b)
# 选取数组元素
b = a[1:4,0]
print(b)
# 选取数组元素
b = a[0:5:2,0:5:2]
print(b)
# 选取数组元素
b = a[:,1]
print(b)
花式索引
花式索引(Fancyindexing)是一个NumPy术语,实际上它是一个索引数组,该索引数组元素的值作为目标数组的索引来选取。若目标数组是一维数组,索引数组的元素值为目标数组元素的索引;若目标数组是二维数组,索引数组的元素值为目标数组的行索引。
b = np.array([11,21,32,56,19,20])
b[[0,2,3,5]] 返回一维数组
[11 32 56 20]
其中列表[0,2,3,5]为索引数组,数组内元素的值对应一维数组b元素的索引。
index = np.array([[0,2],[3,5]])
c = b[index] 返回二维数组
[[11 32]
[56 20]]
其中索引数组是二维数组,目标数组被索引后,会返回一个二维数组,二维数组的行元素来自于索引数组行元素的值对应一维数组b元素的索引。
a = np.array([[10,11,12,18,20],
[22,32,62,82,102],
[36,39,29,27,21],
[79,75,71,70,73],
[91,92,93,94,95]
])
a[[0,2,3]] 返回二维数组
[[10 11 12 18 20]
[36 39 29 27 21]
[79 75 71 70 73]]
其中列表[0,2,3]为索引数组,数组内元素的值对应二维数组a的行索引。
例4 使用花式索引选取数组元素
# 导入numpy库
import numpy as np
# 定义二维数组a
a = np.array([[10,11,12,18,20],
[22,32,62,82,102],
[36,39,29,27,21],
[79,75,71,70,73],
[91,92,93,94,95]
])
# 定义一维数组b
b = np.array([11,21,32,56,19,20])
# 访问数组b索引为0、2、3、5的元素
c = b[[0,2,3,5]]
print(c)
# 建立索引数组index
index = np.array([[0,2],[3,5]])
# 从b数组中构建与索引数组同纬度的数组c
c = b[index]
print(c)
# 访问数组a索引为0、2、3行的元素
c = a[[0,2,3]]
print(c)
布尔索引
布尔索引是建立一个元素类型为布尔值的索引数组,它可以通过指定的布尔值筛选目标数组指定的元素。
索引一维数组
# 定义一维数组b
b = np.array([11,21,32,56,19,20])
# 定义布尔索引数组
index = np.array([True,False,False,True,True,False])
c = b[index]
布尔索引数组index的长度和数组b的长度一致,元素类型都是布尔值,若目标数组元素索引对应的布尔值为True,则该元素被选取。
选取后返回的数组:
[11 56 19]
索引二维数组
# 定义二维数组a
a = np.array([[10,11,12,18,20],
[22,32,62,82,102],
[36,39,29,27,21],
[79,75,71,70,73],
[91,92,93,94,95]
])
# 定义布尔索引数组
index = np.array([True,False,False,True,True])
c = a[index]
布尔索引数组index的长度和数组a的行数一致,若目标数组行索引对应的布尔值为True,则该行元素被选取。
选取后返回的数组:
[[10 11 12 18 20]
[79 75 71 70 73]
[91 92 93 94 95]]
例5 使用布尔索引选取数组元素
# 导入numpy库
import numpy as np
# 定义二维数组a
a = np.array([[10,11,12,18,20],
[22,32,62,82,102],
[36,39,29,27,21],
[79,75,71,70,73],
[91,92,93,94,95]
])
# 定义一维数组b
b = np.array([11,21,32,56,19,20])
# 定义布尔索引数组
index_1 = np.array([True,False,False,True,True,False])
c = b[index_1]
print(c)
# 定义布尔索引数组
index_2 = np.array([True,False,False,True,True])
c = a[index_2]
print(c)
where函数
where函数是对目标数组添加检索条件,符合条件的数组元素被选取。
选取一维数组
# 定义一维数组b
b = np.array([11,21,32,56,19,20])
# 选取数组b的偶数元素
c = np.where(b%2==0)
print(c)
print(b[c])
where函数可以传入条件表达式,使用条件表达式筛选符合条件的数组元素,条件表达式b%2==0返回一个布尔布尔索引数组,用于选取数组中偶数元素。where函数返回的是一个索引数组。
上述代码输出的结果:
(array([2, 3, 5], dtype=int64),)
[32 56 20]
选取二维数组
# 定义二维数组a
a = np.array([[10,11,12,18,20],
[22,32,62,82,102],
[36,39,29,27,21],
[79,75,71,70,73],
[91,92,93,94,95]
])
# 选取数组a的偶数元素
c = np.where(a%2==0)
print(c)
print(a[c])
上述代码输出结果:
(array([0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 4], dtype=int64), array([0, 2, 3, 4, 0, 1, 2, 3, 4, 0, 3, 1, 3], dtype=int64))
[ 10 12 18 20 22 32 62 82 102 36 70 92 94]
返回的索引数组由两个数组构成,分别对应二维数组的行索引和列索引。选取后返回的是一维数组。
例6 使用where选取数组元素
# 导入numpy库
import numpy as np
# 定义二维数组a
a = np.array([[10,11,12,18,20],
[22,32,62,82,102],
[36,39,29,27,21],
[79,75,71,70,73],
[91,92,93,94,95]
])
# 定义一维数组b
b = np.array([11,21,32,56,19,20])
# 选取数组b的偶数元素
c = np.where(b%2==0)
print(c)
print(b[c])
# 选取数组a的偶数元素
c = np.where(a%2==0)
print(c)
print(a[c])