np.where

np.where 矩阵运算,寻找符合条件的值,并返回带有命中元素的横纵坐标

import numpy as np
import cv2 as cv
from skimage.measure import label

img = np.zeros((10,10))
img[:2,:2] = 1
img[3:5,3:5] = 1


print(img)
labels, num = label(img,background=0,return_num=True,connectivity=2)
print(len(np.where(labels==1)[0]))
print(np.where(labels==1))
print(num)
print(labels)
<think> 我们正在讨论NumPy中的`np.where`函数。根据以上的引用,我们可以总结出`np.where`的主要用法有两种: 1. 当只提供一个条件参数时,返回满足条件的元素的索引(坐标)。 2. 当提供三个参数(条件,x,y)时,根据条件从x和y中选择元素来构建新数组:条件为真时选x中的元素,为假时选y中的元素。 下面我们将详细介绍这两种用法,并给出示例。 ## 1. `np.where` 函数介绍 ### 1.1 函数签名 `numpy.where(condition[, x, y])` - `condition`:一个布尔数组或布尔表达式,用于指定条件。 - `x, y`(可选):形状与`condition`相同的数组(或可以广播到相同形状)。当`condition`为True时,从`x`中选取对应位置的元素;为False时,从`y`中选取。 注意:如果只提供`condition`,则返回满足条件(即非零、非False)的元素的坐标(索引)。如果提供三个参数,则返回一个与`condition`形状相同的数组,其中的元素根据条件从`x`或`y`中选取。 ### 1.2 用法一:返回满足条件的索引 当只传入一个条件参数时,`np.where`返回一个元组,元组的每个元素是一个数组,表示满足条件的元素在每个维度上的索引。 #### 示例1:一维数组 ```python import numpy as np a = np.array([1, 2, 0, 4, 0]) indices = np.where(a != 0) print(indices) # 输出:(array([0, 1, 3], dtype=int64),) ``` 这里,`indices`是一个元组,包含一个数组(因为是一维),数组中的元素是满足条件`a != 0`的元素的索引(位置)。 #### 示例2:二维数组 ```python b = np.array([[1, 0, 3], [0, 5, 0], [7, 8, 0]]) indices2d = np.where(b != 0) print(indices2d) # 输出:(array([0, 0, 1, 2, 2], dtype=int64), array([0, 2, 1, 0, 1], dtype=int64)) ``` 对于二维数组,返回的元组包含两个数组:第一个数组是行索引,第二个数组是列索引。满足条件的元素位置为:(0,0), (0,2), (1,1), (2,0), (2,1)。 ### 1.3 用法二:根据条件选择元素(三元操作) 当传入三个参数时,`np.where`类似于三元表达式`x if condition else y`,但它是针对数组的每个元素进行操作的。 #### 示例3:一维数组 ```python c = np.array([1, 2, 3, 4, 5]) d = np.array([10, 20, 30, 40, 50]) result = np.where(c < 3, c, d) print(result) # 输出:[ 1 2 30 40 50] ``` 解释:当`c`中的元素小于3时,取`c`中对应的元素,否则取`d`中对应的元素。所以前两个元素(1和2)来自`c`,后三个元素(3,4,5不满足)来自`d`(即30,40,50)。 #### 示例4:二维数组 ```python e = np.array([[1, 2], [3, 4]]) f = np.array([[10, 20], [30, 40]]) result2d = np.where(e < 3, e, f) print(result2d) # 输出: # [[ 1 2] # [30 40]] ``` 解释:第一个元素1<3 -> 取1;第二个元素2<3 -> 取2;第三个元素3不小于3 -> 取30(来自f的对应位置);第四个元素4不小于3 -> 取40。 注意:`x`和`y`也可以是标量。例如: ```python result_scalar = np.where(e < 3, e, -1) print(result_scalar) # 输出: # [[ 1 2] # [-1 -1]] ``` ## 2. 其他注意事项 ### 2.1 广播规则 当`condition`、`x`、`y`的形状不一致时,会按照广播规则进行广播。例如: ```python condition = np.array([True, False, True]) x = 1 # 标量,广播成[1,1,1] y = np.array([-1, -2, -3]) # 一维数组,形状(3,),与condition形状一致 result_broadcast = np.where(condition, x, y) print(result_broadcast) # 输出:[ 1 -2 1] ``` ### 2.2 与`np.argwhere`的区别 `np.argwhere`函数也可以获取满足条件的元素的索引,但返回的形式不同。`np.argwhere`返回一个二维数组,每一行是一个满足条件的元素的坐标(索引元组)。例如: ```python b = np.array([[1, 0, 3], [0, 5, 0], [7, 8, 0]]) indices_arg = np.argwhere(b != 0) print(indices_arg) # 输出: # [[0 0] # [0 2] # [1 1] # [2 0] # [2 1]] ``` 而`np.where(condition)`返回的是一个元组,元组的每个元素是一个数组,分别表示每个维度上的索引。 ## 3. 示例应用 示例:将数组中所有小于0的元素替换为0,其余保持不变。 ```python arr = np.array([[-1, 2], [-3, 4]]) cleaned = np.where(arr < 0, 0, arr) print(cleaned) # 输出: # [[0 2] # [0 4]] ``` 示例:找出数组中所有正数的位置(索引)。 ```python positions = np.where(arr > 0) print(positions) # 输出:(array([0, 1]), array([1, 1])) 表示位置(0,1)(1,1) ``` ## 总结 `np.where`是NumPy中用于条件索引和条件选择的强大函数。两种主要用法: - 仅条件:返回满足条件的元素的索引(以元组形式,每个维度一个数组)。 - 条件加两个数组:根据条件选择两个数组中的元素来构建新数组。 通过灵活使用`np.where`,可以高效地处理数组的条件操作。 §§相关问题§§ 1. `np.where`和`np.argwhere`有什么区别? 2. 如何使用`np.where`实现更复杂的条件操作? 3. 在什么情况下`np.where`比布尔索引更高效? 4. `np.where`中的`x`和`y`参数可以是不同形状吗?广播规则如何应用? 5. 如何使用`np.where`进行多条件筛选? </think> ### NumPy 的 `np.where()` 函数详解 `np.where()` 是 NumPy 库中用于条件筛选和元素替换的核心函数,其功能根据参数数量分为两种模式: #### 1. **三元条件替换(3 参数模式)** **语法**:`np.where(condition, x, y)` **功能**: - 对数组中的每个元素检查 `condition` 条件 - 条件为 `True` 时选择 `x` 中对应位置的元素 - 条件为 `False` 时选择 `y` 中对应位置的元素 **示例**: ```python import numpy as np arr = np.array([-2, 5, 0, 8, -1]) result = np.where(arr > 0, arr, -10) # 正数保留,负数/零替换为-10 print(result) # 输出: [-10, 5, -10, 8, -10] ``` **数学表示**: $$ \text{result}_i = \begin{cases} x_i & \text{if } \text{condition}_i = \text{True} \\ y_i & \text{if } \text{condition}_i = \text{False} \end{cases} $$ #### 2. **条件索引查询(1 参数模式)** **语法**:`np.where(condition)` **功能**: 返回满足条件元素的**坐标元组**,每个维度对应一个索引数组[^1][^2] **示例**: ```python matrix = np.array([[1, 0], [3, 4]]) indices = np.where(matrix > 2) print(indices) # 输出: (array([1, 1]), array([0, 1])) ``` 结果解读:满足条件的坐标 `(1,0)` 和 `(1,1)` #### 3. 关键特性 1. **广播机制** `x` 和 `y` 可自动广播到 `condition` 的形状: ```python np.where([True, False], 5, [[10, 20]]) # 输出: [[5, 20]] ``` 2. **布尔数组处理** ```python bool_arr = np.array([True, False, True]) np.where(bool_arr, 'A', 'B') # 输出: ['A','B','A'] ``` 3. **多条件组合** 使用 `&` ()、`|` ()、`~` (): ```python arr = np.arange(10) np.where((arr>3) & (arr<7), arr, 0) # 输出: [0,0,0,0,4,5,6,0,0,0] ``` #### 4. 应用场景 1. **数据清洗** ```python data = np.array([-999, 2, 3, -999, 5]) cleaned = np.where(data == -999, np.nan, data) # 异常值替换 ``` 2. **分段函数实现** $$ f(x) = \begin{cases} x^2 & \text{if } x \geq 0 \\ -x & \text{if } x < 0 \end{cases} $$ ```python x = np.array([-2, 3, -5]) f = np.where(x >= 0, x**2, -x) print(f) # 输出: [-2, 9, -5] ``` --- ### 与 `np.argwhere()` 的区别 | 函数 | 返回类型 | 输出结构 | 适用场景 | |---------------|---------------|------------------|------------------| | `np.where()` | **元组** | `(row_idx, col_idx)` | 条件替换/索引获取 | | `np.argwhere()`| **二维数组** | `[[row,col],...]` | 需坐标列表时使用 | 示例对比: ```python arr = np.array([[0, 1], [2, 3]]) print(np.where(arr>1)) # 输出: (array([1,1]), array([0,1])) print(np.argwhere(arr>1))# 输出: [[1 0], [1 1]] ``` --- ### 性能提示 1. 优先使用向量化操作而非循环 2. 复杂条件可拆分为多个 `np.where()` 嵌套 ```python arr = np.random.randn(1000) result = np.where(arr > 1, 10, np.where(arr < -1, -10, 0)) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值