Python科学计算(第2版)
上QQ阅读APP看书,第一时间看更新

2.2.2 比较运算和布尔运算

使用==、>等比较运算符对两个数组进行比较,将返回一个布尔数组,它的每个元素值都是两个数组对应元素的比较结果。例如:

    np.array([1, 2, 3]) < np.array([3, 2, 1])
    array([ True, False, False], dtype=bool)

每个比较运算符也与一个ufunc函数对应,表2-2是比较运算符与ufunc函数的对照表。

表2-2 比较运算符与相应的ufunc函数

由于Python中的布尔运算使用and、or和not等关键字,它们无法被重载,因此数组的布尔运算只能通过相应的ufunc函数进行。这些函数名都以logical_开头,在IPython中使用自动补全可以很容易地找到它们:

    >>> np.logical # 按Tab键进行自动补全
    np.logical_and np.logical_not np.logical_or  np.logical_xor

下面是一个使用logical_or()进行“或运算”的例子:

    a = np.arange(5)
    b = np.arange(4, -1, -1)
    print a == b
    print a > b
    print np.logical_or(a == b, a > b)  # 和 a>=b 相同
    [False False  True False False]
    [False False False  True  True]
    [False False  True  True  True]

对两个布尔数组使用and、or和not等进行布尔运算,将抛出ValueError异常。因为布尔数组中有True也有False,所以NumPy无法确定用户的运算目的:

    a == b and a > b
    ---------------------------------------------------------------------------
    ValueError                                Traceback (most recent call last)
    <ipython-input-13-99b8118687f0> in <module>()
    ----> 1 a == b and a > b
    
    ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

错误信息告诉我们可以使用数组的any()或all()方法,在NumPy中同时也定义了any()和all()函数,它们的用法和Python内置的any()和all()类似。只要数组中有一个元素值为True,any()就返回True;而只有当数组的全部元素都为True时,all()才返回True。

    np.any(a == b)  np.any(a == b) and np.any(a > b)
    --------------  --------------------------------
    True            True                            

以bitwise_开头的函数是位运算函数,包括bitwise_and、bitwise_not、bitwise_or和bitwise_xor等。也可以使用&、~、|和^等操作符进行计算。

对于布尔数组来说,位运算和布尔运算的结果相同。但在使用时要注意,位运算符的优先级比比较运算符高,因此需要使用括号提高比较运算符的运算优先级。例如:

    (a == b) | (a > b)
    array([False, False,  True,  True,  True], dtype=bool)

整数数组的位运算和C语言的位运算相同,在使用时要注意元素类型的符号,例如下面的arange()所创建的数组的元素类型为32位符号整数,因此对正数按位取反将得到负数。以整数0为例,按位取反的结果是0xFFFFFFFF,在32位符号整数中,这个值表示-1。

    ~ np.arange(5)
    array([-1, -2, -3, -4, -5])

而如果对8位无符号整数数组进行按位取反运算:

    ~ np.arange(5, dtype=np.uint8)
    array([255, 254, 253, 252, 251], dtype=uint8)

同样的整数0,按位取反的结果是0xFF,当它是8位无符号整数时,它的值是255。