数组索引
Numpy提供了几种数组索引的方法
切片:与Python内置的列表相似,numpy数组也可以被切片。不过由于数组可能是多维的,你必须明确每一个维度的切片方式:
import numpy as np
# 构建一个形状(shape)为(3, 4)的下述二维数组
# [[ 1 2 3 4]
# [ 5 6 7 8]
# [ 9 10 11 12]]
a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
# 使用切片得到包含前两行中间两列的子数组
# b是一个形状(shape)为(2, 2)的二维数组:
# [[2 3]
# [6 7]]
b = a[:2, 1:3]
# 一个数组的切片是对同一种数据的一种观察视角,因此改变它的值会改变原本的数组
print(a[0, 1]) # 输出 "2"
b[0, 0] = 77 # b[0, 0] 和 a[0, 1]指的是相同的一个数据
print(a[0, 1]) # 输出 "77"
你也可以将整数索引与切片索引整合到一起。然而,这么做会生成一个比原数组阶数更小的数组。另外需要注意的是,这里的切片与MATLAB中处理切片的方式不同:
import numpy as np # 构建一个形状(shape)为(3, 4)的下述二维数组
# [[ 1 2 3 4]
# [ 5 6 7 8]
# [ 9 10 11 12]]
a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
# 两种获得数组中间两行数据的方法。
# 一种是混合整数索引与切片索引,获得一个阶数更小的数组
# 另一种是使用切片索引,获得一个阶数不变的数组
row_r1 = a[1, :] # 对a的第二行的一阶视角
row_r2 = a[1:2, :] # 对a的第二行的二阶视角
print(row_r1, row_r1.shape) # 输出 "[5 6 7 8] (4,)"
print(row_r2, row_r2.shape) # 输出 "[[5 6 7 8]] (1, 4)"
# 在访问数组的列时,我们同样可以找到这样的差异。
col_r1 = a[:, 1]
col_r2 = a[:, 1:2]
print(col_r1, col_r1.shape) # 输出 "[ 2 6 10] (3,)"
print(col_r2, col_r2.shape) # 输出 "[[ 2]
# [ 6]
# [10]] (3, 1)"
整数数组索引:当你使用切片创建索引时,输出结果总会是原数组的子数组。相反的是,整数数组索引允许你使用另一个数组来构建任意数组。例子如下:
import numpy as np
a = np.array([[1,2], [3, 4], [5, 6]])
# 这是整数数组索引的一个例子
# 返回的数组的形状(shape)是(3,)
print(a[[0, 1, 2], [0, 1, 0]]) # 输出 "[1 4 5]"
# 上述整数数组索引的例子等价于以下代码:
print(np.array([a[0, 0], a[1, 1], a[2, 0]])) # 输出 "[1 4 5]"
# 使用整数数组索引时,可以从原数组中得到同一元素:
print(a[[0, 0], [1, 1]]) # 输出 "[2 2]"
# 等同于之前的整数索引示例:
print(np.array([a[0, 1], a[0, 1]])) # 输出 "[2 2]"
有一招可以利用整数索引选择或改变一个矩阵每一行中的一个元素:
import numpy as np
# 先建一个我们要从中选择元素的数组:
a = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
print(a) # 输出 "array([[ 1, 2, 3],
# [ 4, 5, 6],
# [ 7, 8, 9],
# [10, 11, 12]])"
# 创建一个指标数组:
b = np.array([0, 2, 0, 1])
# 使用b中的指标来从a的每一行中选取元素:
print(a[np.arange(4), b]) # 输出 "[ 1 6 7 11]"
# 使用b中的指标来改变a中每一行中满足指标的一个元素:
a[np.arange(4), b] += 10
print(a) # 输出 "array([[11, 2, 3],
# [ 4, 5, 16],
# [17, 8, 9],
# [10, 21, 12]])
布尔型数组索引:布尔型数组索引从一个数组中任意选取元素。通常使用这种索引方式来选择数组中满足一定条件的元素。示例如下:
import numpy as np
a = np.array([[1,2], [3, 4], [5, 6]])
bool_idx = (a > 2) # 寻找比2大的元素;
# 这将会返回一个与a同类型的布尔数组bool_idx,
# 每一个为止的元素都会显示a中同位置的元素是否大于2
print(bool_idx) # 输出 "[[False False]
# [ True True]
# [ True True]]"
# 我们使用布尔数组索引来建立一个一阶数组,其中的元素均满足bool_idx中的True条件。
print(a[bool_idx]) # 输出 "[3 4 5 6]"
# 我们可以在一个简洁的声明中实现上述操作:
print(a[a > 2]) # 输出 "[3 4 5 6]"
为了简洁性,我们省略了很多有关numpy数组索引的内容;如果你想要了解更多的细节,可以参照这个文档