How To Solve Truth value of a Series is ambiguous error. Use a.empty, a.bool(), a.item(), a.any() or a.all() – With Examples

Errors are part of any programming journey. You’ll get the truth value error when checking a condition or filtering rows from pandas dataframe.

You can solve Valueerror Truth value of a Series is ambiguous using the (df[‘column_name’] < Value).any() statement.

Cause Of the Error

  1. The error is caused due to the multiple truth values returned as a series. For example, your code snippet returns a pandas series with values like ['True', 'False', 'True', 'True']. With this type of a series, the if statement won’t be able to decide if the if part needs to be executed or the else statement must be executed.
  2. The error can also occur when you use the and when you want to select rows based on two or more conditions.

Solution

  1. To solve the error in the if condition, you can use any() or all().
  2. To solve the error when using two or more conditions, you need to use the bitwise & or the | operator instead of the and word or or word.

In this tutorial, you’ll learn the different methods available to solve the Truth value of a Series is ambiguous errors while using the pandas dataframe.

Sample Dataframe

This is the sample dataframe used throughout the tutorial.

import pandas as pd

df = pd.DataFrame.from_dict({
    'Product': ['Keyboard', 'Mouse', 'Monitor', 'CPU'],
    'Price': [500, 1500, 9000, 25000],
    'Quantity_Available': [1, 0, 10, 20]
    })

df

Dataframe Will Look Like

ProductPriceQuantity_Available
0Keyboard5001
1Mouse15000
2Monitor900010
3CPU2500020

Scenario 1

Consider the example where you need to print the items in the dataframe that has a price less than 10000.

When you use the below statement, you’ll get the Truth value of a Series is ambiguous error.

if df['Price'] < 10000:
    print(df)

Output

    ---------------------------------------------------------------------------

    ValueError                                Traceback (most recent call last)

    <ipython-input-47-63b310bdde5b> in <module>
    ----> 1 if df['Price'] < 10000:
          2     print(df)


    C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\generic.py in __nonzero__(self)
       1440     @final
       1441     def __nonzero__(self):
    -> 1442         raise ValueError(
       1443             f"The truth value of a {type(self).__name__} is ambiguous. "
       1444             "Use a.empty, a.bool(), a.item(), a.any() or a.all()."


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

Now try to use the statement directly without the if statement.

What the statement does is, checks the price column in every row of the dataframe and if the price is less than 10000, it returns True, else it returns False. The output is returned as a pandas series.

df['Price'] < 20000

You’ll see the below output.

Output

    0     True
    1     True
    2     True
    3    False
    Name: Price, dtype: bool\

Using any() and all()

You can use any() method in the dataframe. It checks all the rows of the dataframe and returns True if any rows are passing the condition specified.

Using the below example, it checks if at least one row in the dataframe contains a price less than 20000. If yes, it returns a single True. You can pass this to the if statement. So the truth value for the if statement is only one value and it can be evaluated without a failure.

Code

(df['Price'] < 20000).any()

Output

    True

To check if every row in the database is passing the desired condition, you can use all() method.

Using the below example, it checks if every row in the dataframe contains a price less than 20000. If yes, it returns a single True, else it returns False.

(df['Price'] < 20000).all()

Output

    False

This is how the any() method and the all() method is used to evaluate the values in the pandas dataframe.

Using any in if

The below code checks if any row in the dataframe contains a price less than 20000, and prints the matching rows.

To print only rows that are passing the condition, you can select rows from the pandas dataframe based on the column value as shown below.

Code

if ((df['Price'] < 20000).any()):
    print(df[df['Price'] < 20000])

Output

       Product  Price  Quantity_Available
    1    Mouse   1500                   0
    2  Monitor   9000                  10

Using all in if

The below code uses the all() method to check if all the rows in the dataframe are passing the condition and it prints all the rows. If all rows don’t pass the condition, it’ll print the error message.

Code

if ((df['Price'] < 20000).all()):
    print(df)
else:
    print("Not all items price is less than 20000")

Output

       Product  Price  Quantity_Available
    1    Mouse   1500                   0
    2  Monitor   9000                  10

Using Lamda Function

The Lambda function is used to apply a specific function to the dataframe rows.

The Truth value of a Series is ambiguous error that may occur while using the lambda function if the condition returns ambiguous series.

The below statement shows the right way of using conditions while using the lambda function.

Code

print(df.apply(lambda row: row[df['Price'] > 1000]))

Output

       Product  Price  Quantity_Available
    1    Mouse   1500                   0
    2  Monitor   9000                  10

The lambda function is applied and the value is updated permanently based on the condition. So when you print the dataframe using df, you’ll see the updated value.

Code

df

Dataframe Will Look Like

ProductPriceQuantity_Available
1Mouse15000
2Monitor900010

Using Bitwise Operators & and |

When you use the and keyword to club multiple conditions to select the columns, you’ll face The truth value of a Series is ambiguous error.

Code

df[(df['Price'] > 1000) and (df['Price'] <= 10000)]

Output

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-3-7920a211822b> in <module>
----> 1  df[(df['Price'] > 1000) and (df['Price'] <= 10000)]

C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\generic.py in __nonzero__(self)
 1440     @final
 1441     def __nonzero__(self):
-> 1442 raise ValueError( 1443             f"The truth value of a {type(self).__name__} is ambiguous. "
 1444             "Use a.empty, a.bool(), a.item(), a.any() or a.all()."

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

Instead of the and keyword, you need to use the bitwise & operator to use multiple conditions.

Code

df[(df['Price'] > 1000) & (df['Price'] <= 10000)]

Now the subset of the dataframe will be returned appropriately.

Dataframe Will Look Like

ProductPriceQuantity_Available
1Mouse15000
2Monitor900010

Using Numpy Logical Operators

You can also use the logical operators provided by the Numpy library.

It supports operations such as logical_and and logical_or.

Code

import numpy as np

df = df[np.logical_and(df['Price'] > 1000, df['Price'] <= 10000)]

df

Dataframe Will Look Like

ProductPriceQuantity_Available
1Mouse15000
2Monitor900010

Conclusion

To summarise, you’ve learned how to solve the ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

If you’ve any questions, please comment below.

You May Also Like

Leave a Comment