当选择对象 obj 是非元组序列对象、ndarray(数据类型为整型或布尔型)或至少具有一个序列对象或 ndarray(数据类型为整型或布尔型)的元组时,会触发高级索引。 高级索引始终返回数据的副本(与返回视图的基本切片相反)。 高级索引有两种类型:整数和布尔。

整数数组索引

整数数组索引允许根据 N 维索引选择数组中的任意项目。 每个整数数组代表该维度的多个索引。 当索引由与被索引数组的维数一样多的整数数组组成时,索引是直接的。

示例 1:

在下面的示例中,从每一行,一个选择特定元素。行索引为[0, 1, 2],列索引为[0, 1, 0]。使用两个索引从给定数组中选择元素。选择包括数组中 (0,0)、(1,1) 和 (2,0) 处的元素。

import numpy as np

#创建数组
x = np.array([[1, 2], [3, 4], [5, 6]])

#使用先进的索引技术
#对数组进行切片
y = x[[0, 1, 2], [0, 1, 0]]

#打印数组
print("x 包含:")
print(x)
print("\ny 包含:")
print(y) 

上述代码的输出将是:

x 包含:
[[1 2]
 [3 4]
 [5 6]]

y 包含:
[1 4 5] 

示例 2:

在下面的示例中,选择了位于 4x3 数组角点的元素。要使用高级索引,需要显式选择所有元素。因此,选择的行索引将为 [0, 0] 和 [3,3],而列索引将为 [0,2] 和 [0,2]。

import numpy as np

#创建数组
x = np.array([[ 0,  1,  2],
              [ 3,  4,  5],
              [ 6,  7,  8],
              [ 9, 10, 11]])

#使用先进的索引技术对数组进行切片
rows = np.array([[0, 0], [3, 3]])
columns = np.array([[0, 2], [0, 2]])
y = x[rows, columns]

print("x 包含:")
print(x)
print("\ny 包含:")
print(y) 

上面的代码将是:

x 包含:
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]

y 包含:
[[ 0  2]
 [ 9 11]] 

可以通过在索引数组中使用 slice :、省略号 ... 或 numpy.newaxis 来组合高级索引和基本索引。

示例 3:

在下面的示例中,切片用于行,高级索引用于列。 当切片同时用于两者时,结果是相同的。 但高级索引会导致复制,并且可能具有不同的内存布局。

import numpy as np

#创建数组
x = np.array([[ 0,  1,  2],
              [ 3,  4,  5],
              [ 6,  7,  8],
              [ 9, 10, 11]])

#using slice 用于行和列的高级索引
y = x[1:4, [1,2]]

#在两个地方都使用切片
z = x[1:4, 1:3]

print("x 包含:")
print(x)
print("\ny 包含:")
print(y)
print("\nz 包含:")
print(z) 

上述代码的输出将是:

x 包含:
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]

y 包含:
[[ 4  5]
 [ 7  8]
 [10 11]]

z 包含:
[[ 4  5]
 [ 7  8]
 [10 11]] 

布尔数组索引

此高级索引当结果对象是比较运算符等布尔运算的结果时,使用索引。

示例 1:

在下面的示例中,返回大于 25 的元素作为布尔数组索引的结果。

import numpy as np

#创建数组
x = np.array([[10, 15, 20], 
              [25, 30, 35],
              [40, 45, 50]])

#使用高级布尔索引
#数组切片技术
y = x[x > 25]

#打印数组
print("x 包含:")
print(x)
print("\ny 包含:")
print(y) 

上述代码的输出将是:

x 包含:
[[10 15 20]
 [25 30 35]
 [40 45 50]]

y 包含:
[30 35 40 45 50] 

示例 2:

同样,此技术可用于从数组中删除所有 NaN(非数字)。考虑下面的示例:

import numpy as np

#创建数组
x = np.array([[10, 15, np.nan], 
              [np.nan, 30, 35],
              [40, np.nan, 50]])

#使用高级布尔索引
#数组切片技术
y = x[~np.isnan(x)]

#打印数组
print("x 包含:")
print(x)
print("\ny 包含:")
print(y) 

上述代码的输出将是:

x 包含:
[[10. 15. nan]
 [nan 30. 35.]
 [40. nan 50.]]

y 包含:
[10. 15. 30. 35. 40. 50.] 

示例 3:

同样,它可用于从数组中过滤掉非复数。考虑下面的示例:

import numpy as np

#创建数组
x = np.array([[10, 15+1j, 20], 
              [25+2j, 30, 35],
              [40, 45, 50+3j]])

#使用高级布尔索引
#数组切片技术
y = x[np.iscomplex(x)]

#打印数组
print("y 包含:")
print(y) 

上述代码的输出将是:

y 包含:
[15.+1.j 25.+2.j 50.+3.j]