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

前端 未结 6 2270
独厮守ぢ
独厮守ぢ 2020-11-21 04:59

I just discovered a logical bug in my code which was causing all sorts of problems. I was inadvertently doing a bitwise AND instead of a logical AND

6条回答
  •  北荒
    北荒 (楼主)
    2020-11-21 05:21

    The reason for the exception is that and implicitly calls bool. First on the left operand and (if the left operand is True) then on the right operand. So x and y is equivalent to bool(x) and bool(y).

    However the bool on a numpy.ndarray (if it contains more than one element) will throw the exception you have seen:

    >>> import numpy as np
    >>> arr = np.array([1, 2, 3])
    >>> bool(arr)
    ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
    

    The bool() call is implicit in and, but also in if, while, or, so any of the following examples will also fail:

    >>> arr and arr
    ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
    
    >>> if arr: pass
    ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
    
    >>> while arr: pass
    ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
    
    >>> arr or arr
    ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
    

    There are more functions and statements in Python that hide bool calls, for example 2 < x < 10 is just another way of writing 2 < x and x < 10. And the and will call bool: bool(2 < x) and bool(x < 10).

    The element-wise equivalent for and would be the np.logical_and function, similarly you could use np.logical_or as equivalent for or.

    For boolean arrays - and comparisons like <, <=, ==, !=, >= and > on NumPy arrays return boolean NumPy arrays - you can also use the element-wise bitwise functions (and operators): np.bitwise_and (& operator)

    >>> np.logical_and(arr > 1, arr < 3)
    array([False,  True, False], dtype=bool)
    
    >>> np.bitwise_and(arr > 1, arr < 3)
    array([False,  True, False], dtype=bool)
    
    >>> (arr > 1) & (arr < 3)
    array([False,  True, False], dtype=bool)
    

    and bitwise_or (| operator):

    >>> np.logical_or(arr <= 1, arr >= 3)
    array([ True, False,  True], dtype=bool)
    
    >>> np.bitwise_or(arr <= 1, arr >= 3)
    array([ True, False,  True], dtype=bool)
    
    >>> (arr <= 1) | (arr >= 3)
    array([ True, False,  True], dtype=bool)
    

    A complete list of logical and binary functions can be found in the NumPy documentation:

    • "Logic functions"
    • "Binary operations"

提交回复
热议问题