pandas-dev/pandas · error · TypeError
Cannot compare a Categorical for op {opname} with type {type
Error message
Cannot compare a Categorical for op {opname} with type {type(other)}.
If you want to compare values, use 'np.asarray(cat) <op> other'. What it means
Raised when a non-equality comparison (__lt__/__gt__/__le__/__ge__) is attempted between a Categorical and a non-Categorical, non-hashable list-like operand. Pandas only supports positional ordering comparisons against scalars or other Categoricals; arbitrary list-likes are ambiguous so it directs you to explicitly convert via np.asarray.
Source
Thrown at pandas/core/arrays/categorical.py:188
if opname not in {"__eq__", "__ge__", "__gt__"}:
# GH#29820 performance trick; get_loc will always give i>=0,
# so in the cases (__ne__, __le__, __lt__) the setting
# here is a no-op, so can be skipped.
mask = self._codes == -1
ret[mask] = fill_value
return ret
else:
return ops.invalid_comparison(self, other, op)
else:
# allow categorical vs object dtype array comparisons for equality
# these are only positional comparisons
# (hashable list-likes such as tuple/range take the branch above and
# are already treated as scalar-like, so only non-standard
# positional list-likes like ``deque`` warn here, GH#62423)
ops.maybe_warn_listlike(other)
if opname not in ["__eq__", "__ne__"]:
raise TypeError(
f"Cannot compare a Categorical for op {opname} with "
f"type {type(other)}.\nIf you want to compare values, "
"use 'np.asarray(cat) <op> other'."
)
if isinstance(other, ExtensionArray) and needs_i8_conversion(other.dtype):
# We would return NotImplemented here, but that messes up
# ExtensionIndex's wrapped methods
return op(other, self)
return getattr(np.array(self), opname)(np.array(other))
func.__name__ = opname
return func
def contains(cat, key, container) -> bool:
"""View on GitHub (pinned to 71959b8cb9)
Solutions
- Convert to numpy first as the message suggests: `np.asarray(cat) < other`.
- If you meant comparing each element to one threshold, pass a scalar: `cat < threshold`.
- Reconsider whether the categorical should be ordered and compared against a scalar category instead.
Example fix
# before cat = pd.Categorical(['a','b','c'], ordered=True) cat < ['c','a','b'] # after import numpy as np cat = pd.Categorical(['a','b','c'], ordered=True) np.asarray(cat) < ['c','a','b']
Defensive patterns
Strategy: fallback
Validate before calling
import numpy as np
def cat_ordering_compare(cat, other, op):
import operator
if not np.isscalar(other):
return op(np.asarray(cat), np.asarray(other))
return op(cat, other) Type guard
def is_scalar_or_hashable(x) -> bool:
import numpy as np
from pandas.api.types import is_hashable
return np.isscalar(x) or is_hashable(x) Try / catch
try:
res = cat < other_listlike
except TypeError as e:
if 'Cannot compare a Categorical' in str(e):
import numpy as np
res = np.asarray(cat) < np.asarray(other_listlike)
else:
raise Prevention
- For list-wise ordering comparisons, convert with np.asarray first.
- Reserve categorical ordering comparisons for scalars or other categoricals.
- Document which comparisons are element-wise vs scalar in your pipeline.
When it happens
Trigger: `cat < [1,2,3]` or `cat >= some_series` where the right side is a list-like and the op is not == or !=. The hashable branch (scalar/tuple category) is exempt; only list-likes hit this.
Common situations: Comparing a categorical column against a parallel list/Series expecting element-wise ordering; or feeding a list of thresholds to a categorical mask.
Related errors
- Unordered Categoricals can only compare equality or not
- Categoricals can only be compared if 'categories' are the sa
- Lengths must match.
- Categorical input must be list-like
- 'values' is not ordered, please explicitly specify the categ
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/75953ba57d27e82a.
Report an issue: GitHub.