问题引入

在对布尔数组进行布尔运算时,and报错,而&正常。后仔细研究了下,发现是没有理清python中的and or与& | 的区别。

In [37]: a=np.arange(-3,3)
Out[37]: array([-3, -2, -1,  0,  1,  2])

In [38]: a>0
Out[38]: array([False, False, False, False,  True,  True])

In [39]: a<2
Out[39]: array([ True,  True,  True,  True,  True, False])

In [40]: a>0 and a<2
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-40-1d57017acc9c> in <module>
----> 1 a>0 and a<2

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

In [41]: (a>0) & (a<2)
Out[41]: array([False, False, False, False,  True, False])

and or是逻辑运算符

and,or,not是逻辑(布尔)运算符,对逻辑(布尔)变量进行与或非运算。但注意:当变量为数值变量时,也会按某种规则进行运算。
如下:

运算符 表达式 运算规则 实例
and a and b a和b为逻辑变量:当a,b都为True,返回True;
a和b为数值变量:返回b
True and False 返回False
2 and 1返回1
or a or b a和b为逻辑变量:当a,b有一个True,返回True;
a和b为数值变量:当a是非0,返回a,否则返回b
True or False 返回True
2 and 1返回2
not not a a为逻辑变量:非运算;
a为数值变量:当a是非0,返回False
not True返回False
not 2返回False

注意:and or无法对布尔数组进行逻辑运算,即问题引入中使用的a>0 and a<2会报错。原因:布尔数组中可能True和False都有,故无法判断运算的目的,因此抛出了ValueError异常,并提示我们先用a.any()或a.all()先将布尔数组变为一个布尔值。

& |是位运算符

所谓位运算符,是把整数(int)转成二进制然后按位进行计算。总结如下,其中a和b为int数值,或布尔值(True,False),也可以是int数组、布尔数组。如果是数组,那么会对对应索引的元素进行位运算。

运算符 表达式 运算规则 实例
& a & b 按位与 1 & 0返回0
1 & 3等价于01 & 11返回1
| a | b 按位或 1 | 0返回1
1 & 3等价于01 | 11返回3(二进制为11)

当a和b为布尔值(True,False),即(1,0)时,此时的&和|位运算符的效果就等价于逻辑运算符。而&和|又支持对数组进行运算,因此可以用&和|来对布尔数组进行逻辑运算。所以上面的的 (a>0) & (a<2)是正确的。不过要注意:因为运算符&的优先级比比较运算符>,<高,所以需要使用括号。

logical_and, logical_or

python中的逻辑运算符and,or,not无法重载,故无法支持对数组进行逻辑运算。但numpy模块提供了标准的函数,来实现对数组进行逻辑运算功能。即np.logical_and, np.logical_or, np.logical_not

In [30]: np.logical_and(a>0,a<2)
Out[30]: array([False, False, False, False,  True, False])

总结

  1. and和or是逻辑运算符,但无法对布尔数组进行逻辑运算;
  2. &和|是位运算符,可对布尔数组进行位运算,但其运算结果等价于逻辑运算
  3. numpy提供了logical_and,logical_or函数,来对布尔数组进行逻辑运算。
Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐