Truth Value of a Series Is Ambiguous. Use A.Empty, A.Bool(), A.Item(), A.Any() or A.All()

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

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().

What you hit was 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 4 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:

  • numpy.logical_or:

      >>> import numpy as np
    >>> np.logical_or(x, y)

    or simply the | operator:

      >>> x | y
  • numpy.logical_and:

      >>> np.logical_and(x, y)

    or simply the & operator:

      >>> x & y

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:

  • If you want to check if your Series is empty:

      >>> x = pd.Series([])
    >>> x.empty
    True
    >>> x = pd.Series([1])
    >>> x.empty
    False

    Python normally interprets the length of containers (like list, tuple, ...) as truth-value if it has no explicit boolean interpretation. So if you want the python-like check, you could do: if x.size or if not x.empty instead of if x.

  • If your Series contains one and only one boolean value:

      >>> x = pd.Series([100])
    >>> (x > 50).bool()
    True
    >>> (x < 50).bool()
    False
  • If you want to check the first and only item of your Series (like .bool() but works even for not boolean contents):

      >>> x = pd.Series([100])
    >>> x.item()
    100
  • If you want to check if all or any item is not-zero, not-empty or not-False:

      >>> x = pd.Series([0, 1, 2])
    >>> x.all() # because one element is zero
    False
    >>> x.any() # because one (or more) elements are non-zero
    True

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

As Michael Szczesny also pointed out in the comment. DataFrame.apply uses a Series as input. The change(name) function defined expects a string. The message ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). comes from trying to compare a Series to a string.

One fix pointed out by Register Sole is to use conditions instead.

condition = (df[‘embark_town’] == 'Southampton')
df[condition]['embark_town'] = 'Manchester'

To keep using apply, the change function would need to look something like this:

def change(series):
if series.name == 'embark_town':
series[series.values == 'Southampton'] = 'Manchester'

return series


Related Topics



Leave a reply



Submit