详解NumPy中np.where() 的两种神奇用法
<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">什么是 np.where()?</a></li><li><a href="#_label1">用法一:三元条件替换(条件 ? 值1 : 值2)</a></li><ul class="second_class_ul"><li><a href="#_lab2_1_0">基础示例</a></li><li><a href="#_lab2_1_1">实际应用:成绩分类</a></li><li><a href="#_lab2_1_2">多条件组合</a></li></ul><li><a href="#_label2">用法二:定位元素索引</a></li><ul class="second_class_ul"><li><a href="#_lab2_2_3">一维数组示例</a></li><li><a href="#_lab2_2_4">二维数组示例</a></li><li><a href="#_lab2_2_5">实际应用:图像处理</a></li></ul><li><a href="#_label3">进阶技巧与注意事项</a></li><ul class="second_class_ul"><li><a href="#_lab2_3_6">1. 广播机制</a></li><li><a href="#_lab2_3_7">2. 直接修改满足条件的值</a></li><li><a href="#_lab2_3_8">3. 多维度索引</a></li></ul><li><a href="#_label4">性能优势</a></li><ul class="second_class_ul"></ul></ul></div><p>在数据科学和数值计算的世界里,NumPy 就像是一把瑞士军刀,而 <code>np.where()</code> 无疑是其中最锋利的工具之一。今天,我们将深入探索这个功能强大的函数,学会如何用它优雅地处理条件逻辑和数据选择。</p><p class="maodian"><a name="_label0"></a></p><h2>什么是 np.where()?</h2>
<p>简单来说,<code>np.where()</code> 是 NumPy 中用于条件选择和元素定位的核心函数。它有两种主要用法:</p>
<ul><li>三元条件替换:根据条件选择不同值</li><li>索引定位:查找满足条件的元素位置</li></ul>
<p>让我们通过实例来探索这两种用法!</p>
<p class="maodian"><a name="_label1"></a></p><h2>用法一:三元条件替换(条件 ? 值1 : 值2)</h2>
<p>这是 <code>np.where()</code> 最常用的形式,语法为:<code>np.where(condition, x, y)</code></p>
<ul><li>condition: 布尔数组(True/False)</li><li>x: 当条件为 True 时使用的值</li><li>y: 当条件为 False 时使用的值</li></ul>
<p class="maodian"><a name="_lab2_1_0"></a></p><h3>基础示例</h3>
<div class="jb51code"><pre class="brush:py;">import numpy as np
# 创建示例数组
temperatures = np.array()
# 标记高温和低温
result = np.where(temperatures > 25, "高温", "舒适")
print(result)
# 输出:['舒适' '高温' '舒适' '高温' '舒适' '舒适']
</pre></div>
<p class="maodian"><a name="_lab2_1_1"></a></p><h3>实际应用:成绩分类</h3>
<div class="jb51code"><pre class="brush:py;">scores = np.array()
# 根据分数分类
grade = np.where(scores >= 90, "A",
np.where(scores >= 80, "B",
np.where(scores >= 70, "C",
np.where(scores >= 60, "D", "F"))))
print(grade)
# 输出:['C' 'A' 'F' 'B' 'F' 'D' 'B']
</pre></div>
<p class="maodian"><a name="_lab2_1_2"></a></p><h3>多条件组合</h3>
<div class="jb51code"><pre class="brush:py;">data = np.array()
# 组合条件:大于10且小于20
result = np.where((data > 10) & (data < 20), data, 0)
print(result)# 输出:
# 使用 | 表示 OR 条件
result = np.where((data < 10) | (data > 20), data, -1)
print(result)# 输出:[ -125 7-130 522]
</pre></div>
<p class="maodian"><a name="_label2"></a></p><h2>用法二:定位元素索引</h2>
<p>当我们只提供条件参数时,<code>np.where()</code> 会返回满足条件元素的索引。</p>
<p>语法:<code>np.where(condition)</code></p>
<p class="maodian"><a name="_lab2_2_3"></a></p><h3>一维数组示例</h3>
<div class="jb51code"><pre class="brush:py;">arr = np.array()
# 找到非零元素的索引
non_zero_indices = np.where(arr != 0)
print(non_zero_indices)# 输出:(array(),)
# 提取非零值
print(arr)# 输出:
</pre></div>
<p class="maodian"><a name="_lab2_2_4"></a></p><h3>二维数组示例</h3>
<div class="jb51code"><pre class="brush:py;">matrix = np.array([,
,
])
# 找到值大于3的元素位置
rows, cols = np.where(matrix > 3)
print("行索引:", rows) # 输出:
print("列索引:", cols) # 输出:
print("对应值:", matrix)# 输出:
</pre></div>
<p class="maodian"><a name="_lab2_2_5"></a></p><h3>实际应用:图像处理</h3>
<div class="jb51code"><pre class="brush:py;"># 创建一个简单的图像矩阵 (5x5)
image = np.array([,
,
,
,
])
# 找到高光区域(值>200)
highlight_rows, highlight_cols = np.where(image > 200)
print("高光像素位置:")
for r, c in zip(highlight_rows, highlight_cols):
print(f"({r}, {c}) - 值: {image}")
# 输出:
# (0, 3) - 值: 200
# (0, 4) - 值: 210
# (1, 2) - 值: 255
# (2, 0) - 值: 220
# (2, 3) - 值: 190 -> 注意:190不大于200,实际应为 (2, 4): 200
# 更正:矩阵中 (2,4) 是200,所以应包含
</pre></div>
<p class="maodian"><a name="_label3"></a></p><h2>进阶技巧与注意事项</h2>
<p class="maodian"><a name="_lab2_3_6"></a></p><h3>1. 广播机制</h3>
<p><code>np.where()</code> 支持 NumPy 的广播机制,使不同形状的数组能够一起工作:</p>
<div class="jb51code"><pre class="brush:py;"># 二维条件与一维值组合
condition_2d = np.array([, ])
result = np.where(condition_2d, , 0)
print(result)
# 输出:
# [
#[ 0 20]]
</pre></div>
<p class="maodian"><a name="_lab2_3_7"></a></p><h3>2. 直接修改满足条件的值</h3>
<div class="jb51code"><pre class="brush:py;">data = np.array()
# 将小于10的值替换为0
data = 0
print(data)# 输出:[ 0 120 150 10]
</pre></div>
<p class="maodian"><a name="_lab2_3_8"></a></p><h3>3. 多维度索引</h3>
<p>对于三维或更高维数组,<code>np.where()</code> 同样适用:</p>
<div class="jb51code"><pre class="brush:py;"># 创建3x3x3数组
cube = np.random.randint(0, 10, (3, 3, 3))
# 找到所有大于8的元素
indices = np.where(cube > 8)
# 输出三维索引
print("维度0:", indices)
print("维度1:", indices)
print("维度2:", indices)
# 访问这些元素
print("满足条件的值:", cube)
</pre></div>
<p class="maodian"><a name="_label4"></a></p><h2>性能优势</h2>
<p>与 Python 循环相比,<code>np.where()</code> 有显著的性能优势:</p>
<div class="jb51code"><pre class="brush:py;">import time
large_array = np.random.rand(10**6)
# 使用循环
start = time.time()
result_loop =
print("循环耗时:", time.time() - start)
# 使用 np.where
start = time.time()
result_np = np.where(large_array > 0.5, large_array*2, large_array/2)
print("np.where耗时:", time.time() - start)
</pre></div>
<p>测试结果(可能因机器而异):</p>
<blockquote><p>循环耗时: 0.45秒<br />np.where耗时: 0.02秒</p></blockquote>
頁:
[1]