NumPy如何实现类似Python原生的逐元素链式比较
NumPy逐元素链式比较实现方法
Python原生支持链式比较语法,例如:
1 < 2 < 3 < 4
但NumPy无法直接复用该语法实现逐元素的多条件链式判断。
多数人首先会想到使用np.logical_and实现逻辑与判断,但该函数仅支持传入2个输入参数:
- 3个数组比较时,两两传参还可以正常运行:
import numpy as np a = np.array([1,2,4,5,6]) b = np.array([2,6,1,5,6]) c = np.array([7,4,6,6,8]) np.logical_and((a <= b),(b <= c))
- 当参与比较的数组达到4个及以上时,要么嵌套多层
np.logical_and写起来十分繁琐,要么直接传入3个及以上比较条件会直接触发参数错误:
a = np.array([1,2,4,5,6]) b = np.array([2,6,1,5,6]) c = np.array([7,4,6,6,8]) d = np.array([8,9,9,9,2]) np.logical_and((a <= b),(b <= c)) # 正常运行 np.logical_and((b <= c),(c <= d)) # 正常运行 np.logical_and((a <= b),(b <= c),(c <= d)) # 报错,参数数量超出限制
上述问题在高维数组场景下同样存在,二维数组测试数据示例:
a = np.array([[1,2,3], [4,5,6]]) b = np.array([[2,6,3], [1,5,6]]) c = np.array([[7,4,3], [6,6,8]]) d = np.array([[8,9,3], [9,9,2]])
可用实现方案
有两种简洁写法可以适配任意数量数组的逐元素链式比较,对一维、二维及更高维数组均生效:
- 写法1:用
&运算符连接所有相邻数组的比较结果
注意每个比较表达式必须单独加括号,避免运算符优先级导致逻辑错误。例如实现a <= b <= c <= d的逐元素判断:
该写法返回和输入数组同形状的布尔数组,每个位置的值对应该位置元素是否满足全部链式比较条件。result = (a <= b) & (b <= c) & (c <= d) - 写法2:收集所有相邻比较的布尔条件,用
np.all沿0轴判断全True
当参与比较的数组数量很多时,该写法不需要手动拼接多个&连接符,代码更易维护:conditions = [a <= b, b <= c, c <= d] result = np.all(conditions, axis=0)
两种写法返回的结果完全一致,用上述二维测试数据验证,最终输出结果为:
[[ True False True] [False True False]]
逐位置校验即可确认结果符合链式比较的预期。
注意:禁止直接在NumPy数组上套用原生链式比较语法
a <= b <= c。Python会将该语法解析为(a <= b) and (b <= c),而原生and运算符无法处理数组类型的布尔值,会触发“数组真值不明确”的报错。
内容的提问来源于stack exchange,提问作者Muhammad Yasirroni
相关产品推荐
相关产品推荐

