pythonpandasfilterconditional-statementsvalueerror

Truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()


I want to filter my dataframe with an or condition to keep rows with a particular column's values that are outside the range [-0.25, 0.25]. I tried:

df = df[(df['col'] < -0.25) or (df['col'] > 0.25)]

But I get the error:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().


Solution

  • The or and and Python statements require truth-values. For pandas, these are considered ambiguous, so you should use "bitwise" | (or) or & (and) operations:

    df = df[(df['col'] < -0.25) | (df['col'] > 0.25)]
    

    These are overloaded for these kinds of data structures to yield the element-wise or or and.


    Just to add some more explanation to this statement:

    The exception is thrown when you want to get the bool of a pandas.Series:

    >>> import pandas as pd
    >>> x = pd.Series([1])
    >>> bool(x)
    ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
    

    You hit a place where the operator implicitly converted the operands to bool (you used or but it also happens for and, if and while):

    >>> x or x
    ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
    >>> x and x
    ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
    >>> if x:
    ...     print('fun')
    ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
    >>> while x:
    ...     print('fun')
    ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
    

    Besides these four statements, there are several Python functions that hide some bool calls (like any, all, filter, ...). These are normally not problematic with pandas.Series, but for completeness I wanted to mention these.


    In your case, the exception isn't really helpful, because it doesn't mention the right alternatives. For and and or, if you want element-wise comparisons, you can use:

    If you're using the operators, then be sure to set your parentheses correctly because of operator precedence.

    There are several logical NumPy functions which should work on pandas.Series.


    The alternatives mentioned in the Exception are more suited if you encountered it when doing if or while. I'll shortly explain each of these: