NumPy 2.x 完全指南【三十一】布尔数组索引
文章目录
- 1. 概述
- 2. 一维数组
- 3. 二维数组
- 3.1 部分索引
- 3.2 全索引
- 4. 三维数组
- 4.1 部分索引
- 4.2 全索引
1. 概述
定义:通过布尔掩码(True
/False
值)选择满足条件的元素。
核心规则:
- 布尔数组形状必须完全匹配被索引数组的对应维度:
- 若布尔数组形状为 (
d1, d2
),则被索引数组的前两维必须为 (d1, d2, ...
),若布尔数组维数不足,则等效于在尾部补全:
。 - 也可以结合全切
:
表示对应位置匹配任何长度,剩余位置则需要一一对应。例如,数组形状为(3,4)
,则布尔数组可以为(4)
,但需要使用[:, mask_arr]
执行操作。
- 若布尔数组形状为 (
- 布尔索引不支持广播,需手动对齐形状。
- 结果形状:布尔数组中
True
的数量+
未索引维度的形状。
2. 一维数组
一维数组只有一个维度,所以布尔数组长度必须与原数组长度一致。
示例 1 ,筛选大于 30
的元素,布尔索引数组对应位置为 True
的元素将会返回:
# 一维数组
arr = np.array([10, 20, 30, 40, 50, 60])# 单条件筛选:选择大于 30 的元素
condition1 = arr > 30
print(condition1)
# [False False False True True True]result = arr[condition1] # 等价于 arr[arr > 30]
print( result)
# 输出: [40 50 60]
执行流程如下所示:
示例 2 ,多条件组合筛选的元素:
# 多条件组合:选择 20 ~ 50 之间的元素
condition2 = (arr > 20) & (arr < 50)
result = arr[condition2]
print(result)
示例 3 ,当布尔数组长度和原数组不一致时会报错:
result = arr[[False, True]]
print( result)
# boolean index did not match indexed array along axis 0; size of axis is 6 but size of corresponding boolean axis is 2
示例 4 ,在使用整数数组索引时,索引对象可以是任意形状的,布尔数组索引则不支持:
mask = [[False, False, False], [True, True, True]]
print(arr[mask])
# IndexError: too many indices for array: array is 1-dimensional, but 2 were indexed
3. 二维数组
二维数组有两个轴,高级索引表达式可以有以下几种形式:
arr[index1,index2]
(全索引)。arr[index1]
(部分索引)。
3.1 部分索引
arr[index1]
(部分索引):仅作用于轴 0
(行),默认轴 1
完全保留,等效于arr[index, :]
。
索引对象的形状必须完全匹配被索引数组的对应维度,二维数组的形状为 (m,n)
,索引数组的形状可以为:
(m,n)
。(m)
。
示例 1 ,索引对象是一维数组时,其长度必须等于 (m)
,表示 True
作用于 0
轴(行),用于筛选整行:
# 二维数组
arr = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]]) # 形状 (3,3)
# 布尔索引 (长度 =3)
index1 = [True, False, True] # 选中第 0 行和第 2 行result = arr[index1]
print(result)
# [[1 2 3]
# [7 8 9]]
示例 2 ,索引对象的长度必须等于行数,否则会报错:
# 布尔索引 (长度 =2)
index1 = [True, False]result = arr[index1]
# IndexError: boolean index did not match indexed array along axis 0; size of axis is 3 but size of corresponding boolean axis is 2
示例 3 ,(m,n)
则是和原数组的形状完全一样,用于逐元素筛选,True
位置对应的元素将被返回:
# 二维数组
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # 形状 (3,3)
element_mask = np.array([[True, False, True],[False, True, False],[True, False, True]])
result = arr[element_mask] # 返回一维数组
print(result)
# 输出:[1 3 5 7 9] ( True 位置对应的元素)
3.2 全索引
在使用整数数组索引时,多个索引对象会进行位置匹配和广播,并支持任意维度的索引数组。但是在布尔数组索引中,索引对象必须匹配目标维度:
index1
:必须是一个长度等于arr
行数的一维布尔数组(长度为1
时支持广播)。index2
:必须是一个长度等于arr
列数的一维布尔数组(长度为1
时支持广播)。
示例 1 ,使用 arr[index1,index2]
时,返回的是一个一维数组:
# 创建 5x4 数字矩阵
arr = np.array([[10, 11, 12, 13],[20, 21, 22, 23],[30, 31, 32, 33],[40, 41, 42, 43],[50, 51, 52, 53]])row_bool = [False, True, False, True, True] # 长度 = 行数
col_bool = [True, False, True, True] # 长度 = 行数
result = arr[row_bool, col_bool]
print(result)
# [20 42 53]
示例 2 ,只有索引对象的长度为 1
时,才支持广播机制:
# 行选择
row_bool = [True, False, True, True, False] # True: 0,2,3
# 列选择 (标量→广播)
col = [True]
col_bool = arr[row_bool, col_bool]
print(result)
示例 3,还可以结合 :
表示选择所有行:
arr = np.array([[1, 2],[4, 5],[7, 8]]) # 形状 (3,2)col_mask = np.array([True, False]) # 形状 (2,)
result = arr[:, col_mask] # 选择第 0 列
print(result)
# 输出:
# [[1]
# [4]
# [7]]
4. 三维数组
在了解完二维数组的机制后,对于三维或者更多维度数组的操作也是一样了。
4.1 部分索引
比如三维数组的形状为 (m,n,k)
,那么布尔索引数组的形状可以为:
(m,n)
。(m)
。
示例 1 ,使用 (m,n)
等效于 (m,n,:)
进行逐行筛选:
arr = np.arange(24).reshape(2, 3, 4)
print(arr)
# [[[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
#
# [[12 13 14 15]
# [16 17 18 19]
# [20 21 22 23]]]
mask_rows = np.array([[True, False, True], # 层 0:选第 0 行和第 2 行[False, True, False], # 层 1:选第 1 行[True, True, False] # 层 2:选第 0 行和第 1 行
]) # 形状 (3,3)result = arr[mask_rows]
print(result)
# [[ 0 1 2]
# [ 6 7 8]
# [12 13 14]
# [18 19 20]
# [21 22 23]]
示例 2 ,使用 (m)
等效于 (m,:,:)
进行逐层筛选:
mask_layers = np.array([True, False, True]) # 选择第 0 层和第 2 层
result = arr[mask_layers]
print(result)
# [[[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]]
#
# [[18 19 20]
# [21 22 23]
# [24 25 26]]]
示例 3 ,使用 :
每层逐元素筛选:
arr = np.arange(24).reshape(2, 3, 4)
print(arr)
# [[[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
#
# [[12 13 14 15]
# [16 17 18 19]
# [20 21 22 23]]]
mask_arr = np.array([[True, False, True, True],[False, True, False, True],[True, False, True, True]
]) # 形状 (3,4)
# 第一层: [ 0 2 3 5 7 8 10 11]
# 第二层:[12 14 15 17 19 20 22 23]
result = arr[:, mask_arr]
print(result)
# [[ 0 2 3 5 7 8 10 11]
# [12 14 15 17 19 20 22 23]]
4.2 全索引
示例 1 ,使用 (m,n,k)
进行逐元素筛选:
# 创建3x3x3三维数组
arr = np.arange(27).reshape(3, 3, 3)
"""
第0层: [[0, 1, 2],[3, 4, 5],[6, 7, 8]]
第1层: [[9, 10, 11],[12, 13, 14],[15, 16, 17]]
第2层: [[18, 19, 20],[21, 22, 23],[24, 25, 26]]
"""
mask_full = np.array([[[True, False, True],[False, True, False],[True, False, True]],[[False, True, False],[True, False, True],[False, True, False]],[[True, False, True],[False, True, False],[True, False, True]]
]) # 形状 (3,3,3)result = arr[mask_full]
print( result)
# 输出: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26]