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
- 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, theif
statement won’t be able to decide if the if part needs to be executed or theelse
statement must be executed. - The error can also occur when you use the
and
when you want to select rows based on two or more conditions.
Solution
- To solve the error in the
if
condition, you can useany()
orall()
. - To solve the error when using two or more conditions, you need to use the bitwise
&
or the|
operator instead of theand
word oror
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.
Table of Contents
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
Product | Price | Quantity_Available | |
---|---|---|---|
0 | Keyboard | 500 | 1 |
1 | Mouse | 1500 | 0 |
2 | Monitor | 9000 | 10 |
3 | CPU | 25000 | 20 |
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
Product | Price | Quantity_Available | |
---|---|---|---|
1 | Mouse | 1500 | 0 |
2 | Monitor | 9000 | 10 |
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
Product | Price | Quantity_Available | |
---|---|---|---|
1 | Mouse | 1500 | 0 |
2 | Monitor | 9000 | 10 |
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
Product | Price | Quantity_Available | |
---|---|---|---|
1 | Mouse | 1500 | 0 |
2 | Monitor | 9000 | 10 |
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.