NumPy 布尔数组索引的实现示例
<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">1 与原数组同形的布尔数组索引</a></li><ul class="second_class_ul"><li><a href="#_lab2_0_0">1.1 基本用法:筛选满足条件的元素</a></li><li><a href="#_lab2_0_1">1.2 赋值操作:批量修改满足条件的元素</a></li></ul><li><a href="#_label1">2 按维度的一维布尔数组索引</a></li><ul class="second_class_ul"><li><a href="#_lab2_1_2">2.1 选择某一维度的切片(以二维数组为例)</a></li><li><a href="#_lab2_1_3">2.2 选择列(第二个维度)</a></li><li><a href="#_lab2_1_4">2.3 同时选择行和列</a></li></ul></ul></div><p>在 NumPy 中,布尔数组索引是一种强大的元素选择方式,它通过 “True/False” 的逻辑判断筛选元素。以下是具体用法及带输出注释的示例代码。</p><p class="maodian"><a name="_label0"></a></p><h2>1 与原数组同形的布尔数组索引</h2>
<p>创建和原数组形状相同的布尔数组,True 表示选择该元素,False 表示排除。</p>
<p class="maodian"><a name="_lab2_0_0"></a></p><h3>1.1 基本用法:筛选满足条件的元素</h3>
<div class="jb51code"><pre class="brush:py;">import numpy as np
# 创建一个3行4列的数组(元素0-11)
a = np.arange(12).reshape(3, 4)
print("原数组a:")
print(a)
# Output:
# [[ 0123]
#[ 4567]
#[ 89 10 11]]
# 创建与a同形的布尔数组:判断a中元素是否大于4
b = a > 4
print("\n布尔数组b(a > 4的结果):")
print(b)
# Output:
# [
#
#[ TrueTrueTrueTrue]]
# 用布尔数组b索引a,提取所有True位置的元素(返回一维数组)
selected_elements = a
print("\n筛选出的元素:")
print(selected_elements)
# Output: [ 56789 10 11]
</pre></div>
<p class="maodian"><a name="_lab2_0_1"></a></p><h3>1.2 赋值操作:批量修改满足条件的元素</h3>
<div class="jb51code"><pre class="brush:py;"># 继续使用上面的数组a和布尔数组b
a = 0# 将a中所有>4的元素赋值为0
print("修改后的数组a:")
print(a)
# Output:
# [
#
#]
</pre></div>
<p class="maodian"><a name="_label1"></a></p><h2>2 按维度的一维布尔数组索引</h2>
<p>对每个维度提供一维布尔数组(长度需与对应维度一致),用于选择该维度的 “切片”。</p>
<p class="maodian"><a name="_lab2_1_2"></a></p><h3>2.1 选择某一维度的切片(以二维数组为例)</h3>
<div class="jb51code"><pre class="brush:py;">import numpy as np
a = np.arange(12).reshape(3, 4)# 3行4列,行索引0-2,列索引0-3
print("原数组a:")
print(a)
# Output:
# [[ 0123]
#[ 4567]
#[ 89 10 11]]
# 行选择的布尔数组:长度=行数(3),选择第2、3行(索引1、2)
b1 = np.array()
# 列选择的布尔数组:长度=列数(4),选择第1、3列(索引0、2)
b2 = np.array()
# 选择行(第一个维度):等价于a
print("\n选择行(b1为):")
print(a)
# Output:
# [[ 4567]
#[ 89 10 11]]
</pre></div>
<p class="maodian"><a name="_lab2_1_3"></a></p><h3>2.2 选择列(第二个维度)</h3>
<div class="jb51code"><pre class="brush:py;">print("\n选择列(b2为):")
print(a[:, b2])
# Output:
# [[ 02]
#[ 46]
#[ 8 10]]
</pre></div>
<p class="maodian"><a name="_lab2_1_4"></a></p><h3>2.3 同时选择行和列</h3>
<div class="jb51code"><pre class="brush:py;">print("\n同时选择行和列(b1和b2结合):")
print(a)
# Output:
# 解释:b1选择行1、2,b2选择列0、2 → 取(1,0)和(2,2)位置的元素:4和10
</pre></div> 好详细的教程!感谢楼主的分享~
之前一直对NumPy的布尔索引一知半解,看完终于搞明白了同形布尔数组和一维布尔数组的区别。
补充一个小技巧:布尔索引返回的是原数组的视图还是副本这个问题经常让人困惑。实际上,当用作左值赋值时是修改原数组,当用作右值提取元素时返回的是副本(展平后的一维数组)。
另外对于大规模数据筛选,np.where函数配合布尔数组也很好用,比如:
# 获取满足条件的元素索引
indices = np.where(a > 4)
print(indices)
# 可以直接用这些索引访问原数组
print(a)
再次感谢楼主的清晰讲解,收藏了!希望以后能出更多NumPy相关的教程~
评分:5星 楼主这篇教程整理得太清晰了! 之前看官方文档总觉得布尔索引的逻辑有点绕,看完你的分类讲解瞬间通透了。回复楼上 补充的视图与副本机制以及 np.where 的用法非常到位,确实能避开不少内存和性能上的坑!我也来抛砖引玉,补充一个新手写多条件筛选时最容易翻车的地方:位运算符优先级。在组合多个布尔条件时,一定要记得给每个条件加上小括号,不然 Python 的 & 和 | 会优先于比较运算符执行,直接报错或者得出诡异的结果。正确写法如下:# 错误示范:会报 TypeError 或逻辑错误
mask = arr > 2 & arr < 5
正确示范:务必加括号
mask = (arr > 2) & (arr < 5)
result = arr
另外,如果需要对二维数据进行按行或按列的批量筛选,搭配 np.any 和 np.all 会非常高效。比如想快速挑出“至少包含一个负数”的所有行:row_mask = np.any(arr < 0, axis=1)
print(arr)
感谢楼主的干货分享,期待更多 NumPy 实战技巧!大家一起交流进步~
頁:
[1]