高级索引
当选择对象obj是非元组序列对象,ndarray(数据类型为整数或bool)或具有至少一个序列对象或ndarray(数据类型为integer或bool)的元组时,将触发高级索引。高级索引有两种类型:整数和布尔值。
高级索引始终返回数据的副本(与返回视图的基本切片形成对比)。
警告
高级索引的定义意味着x[(1,2,3),]根本不同于x[(1,2,3)]。后者相当于x[1,2,3]触发基本选择,而前者将触发高级索引。一定要明白为什么会这样。
同时认识到x[[1,2,3]]将触发高级索引,而由于上面提到的不推荐的数字兼容性, x[[1,2,slice(None)]]将触发基本切片。
整数数组索引
整数数组索引允许根据数组的N维索引选择数组中的任意项。每个整数数组表示该维度的许多索引。
纯整数数组索引
当索引包含尽可能多的整数数组时,索引的数组具有维度,索引是直接的,但与切片不同。
高级索引始终作为一个广播和迭代:
result[i_1, ..., i_M] == x[ind_1[i_1, ..., i_M], ind_2[i_1, ..., i_M],
..., ind_N[i_1, ..., i_M]]
请注意,结果形状与(广播)索引数组形状相同。ind_1, ..., ind_N
例
从每一行开始,应选择一个特定元素。行索引是just ,列索引指定要为相应行选择的元素。将两者结合使用可以使用高级索引解决任务:0, 1, 2
>>> >>> x = np.array([[1, 2], [3, 4], [5, 6]]) >>> x[[0, 1, 2], [0, 1, 0]] array([1, 4, 5])
为了实现类似于上面的基本切片的行为,可以使用广播。该功能ix_可以帮助这种广播。通过示例可以最好地理解这一点。
例
从4x3阵列中,应使用高级索引选择角元素。因此,列是其中之一的所有元素和行是需要选择的行。要使用高级索引,需要明确选择所有元素。使用前面解释的方法可以写:0, 2
>>> >>> x = array([[ 0, 1, 2], ... [ 3, 4, 5], ... [ 6, 7, 8], ... [ 9, 10, 11]]) >>> rows = np.array([[0, 0], ... [3, 3]], dtype=np.intp) >>> columns = np.array([[0, 2], ... [0, 2]], dtype=np.intp) >>> x[rows, columns] array([[ 0, 2], [ 9, 11]])
但是,由于上面的索引数组只是重复自身,因此可以使用广播(比较诸如此类的操作 )来简化:rows[:, np.newaxis] + columns
>>> >>> rows = np.array([0, 3], dtype=np.intp) >>> columns = np.array([0, 2], dtype=np.intp) >>> rows[:, np.newaxis] array([[0], [3]]) >>> x[rows[:, np.newaxis], columns] array([[ 0, 2], [ 9, 11]])
这种广播也可以使用以下功能实现ix_:
>>> >>> x[np.ix_(rows, columns)] array([[ 0, 2], [ 9, 11]])
请注意,如果没有np.ix_调用,只会选择对角线元素,如上例所示。对于使用多个高级索引进行索引,这个差异是最重要的。
结合高级索引和基本索引
当至少有一个slice(:),省略号(...)或newaxis 索引(或者数组的维度多于高级索引)时,行为可能会更复杂。这就像连接每个高级索引元素的索引结果一样
在最简单的情况下,只有一个单一的指标先进。单个高级索引可以例如替换切片,并且结果数组将是相同的,但是,它是副本并且可以具有不同的存储器布局。当可能时,切片是优选的。