pandas-dev/pandas · error · TypeError
boolean value of an expression is ambiguous
Error message
boolean value of an expression is ambiguous
What it means
Raised by Expression.__bool__ when Python tries to coerce a pandas.api.typing.Expression (produced by pd.col(...)) into a single bool. Expression represents a deferred column operation and evaluates to a per-row Series, so a single truth value is undefined (like NumPy's ambiguous-truth error). The method is typed NoReturn so any bool(ctx) usage fails.
Solutions
- Use the Expression where it will be evaluated against a DataFrame: df.loc[pd.col('a') > 0].
- If you need a scalar test, evaluate first: result = pd.col('a')._eval_expression(df); then test result.
- Replace `if expr:` with the boolean reduction you actually want (e.g. (expr).any()).
Example fix
// before
expr = pd.col('speed') > 100
if expr:
...
// after
df = df.assign(fast=(pd.col('speed') > 100)) Defensive patterns
Strategy: type-guard
Validate before calling
from pandas.api.typing import Expression
if isinstance(x, Expression):
raise TypeError('Expression must be evaluated against a DataFrame before bool()') Type guard
def is_expression(x) -> bool:
from pandas.api.typing import Expression
return isinstance(x, Expression) Prevention
- Never use a pd.col(...) result in a Python if/and/or/assert.
- Evaluate Expressions against a DataFrame before consuming them.
- Type-check inputs in generic functions that call bool().
When it happens
Trigger: if pd.col('a'): ...; bool(pd.col('a') > 0); using an Expression directly as the test in assert or `and`/`or`; passing an Expression to a function that calls bool() on it (e.g. filter()).
Common situations: Treating pd.col('x') like a scalar in a Python conditional; building an Expression inside an if instead of passing it to .loc/.assign/.query where it is evaluated against a DataFrame.
Related errors
- Expression objects are not copiable
- Expression objects are not iterable
- Column ' ' not found in given DataFrame. Hint: did you mean…
- Expected Hashable, got
- Accumulation not supported for
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/c2f06d9fe05a5196.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/col.py:357
evaluated = []
for condition, replacement in caselist:
if isinstance(condition, Expression):
condition = condition._eval_expression(df)
if isinstance(replacement, Expression):
replacement = replacement._eval_expression(df)
evaluated.append((condition, replacement))
return ser.case_when(evaluated)
# Keep repr compact; caselist may be large.
repr_str = f"{self!r}.case_when(...)"
return Expression(func, repr_str)
def __repr__(self) -> str:
return self._repr_str or "Expr(...)"
# Unsupported ops
def __bool__(self) -> NoReturn:
raise TypeError("boolean value of an expression is ambiguous")
def __iter__(self) -> NoReturn:
raise TypeError("Expression objects are not iterable")
def __copy__(self) -> NoReturn:
raise TypeError("Expression objects are not copiable")
def __deepcopy__(self, memo: dict[int, Any] | None) -> NoReturn:
raise TypeError("Expression objects are not copiable")
@set_module("pandas")
def col(col_name: Hashable) -> Expression:
"""
Generate deferred object representing a column of a DataFrame.
Any place which accepts ``lambda df: df[col_name]``, such as
:meth:`DataFrame.assign` or :meth:`DataFrame.loc`, can also acceptView on GitHub (pinned to 3b7651241d)