pandas-dev/pandas · error · TypeError
Cannot compare types {type_names[0]!r} and {type_names[1]!r}
Error message
Cannot compare types {type_names[0]!r} and {type_names[1]!r} What it means
TypeError raised in _check_comparison_types during replace: when an element-wise comparison between the array and a value reduces to a scalar bool (not an element-wise array), pandas infers the two types are not comparable and reports the ndarray dtype and the scalar type. This prevents silently returning an all-False mask.
Source
Thrown at pandas/core/array_algos/replace.py:81
-------
mask : array-like of bool
"""
if isna(b):
return ~mask
def _check_comparison_types(
result: ArrayLike | bool, a: ArrayLike, b: Scalar | Pattern
) -> None:
"""
Raises an error if the two arrays (a,b) cannot be compared.
Otherwise, returns the comparison result as expected.
"""
if is_bool(result) and isinstance(a, np.ndarray):
type_names = [type(a).__name__, type(b).__name__]
type_names[0] = f"ndarray(dtype={a.dtype})"
raise TypeError(
f"Cannot compare types {type_names[0]!r} and {type_names[1]!r}"
)
if not regex or not should_use_regex(regex, b):
# TODO: should use missing.mask_missing?
op = lambda x: operator.eq(x, b)
else:
op = np.vectorize(
lambda x: (
bool(re.search(b, x))
if isinstance(x, str) and isinstance(b, (str, Pattern))
else False
),
otypes=[bool],
)
# GH#32621 use mask to avoid comparing to NAs
if isinstance(a, np.ndarray) and mask is not None:View on GitHub (pinned to 3b7651241d)
Solutions
- Apply replace per column so each comparison is type-compatible.
- Cast the value to match the column dtype before replacing.
- Use a regex pattern only on string columns and a separate numeric value on numeric columns.
Example fix
# before
df.replace(re.compile('x'), 0) # on a numeric df
# after
df.apply(lambda c: c.replace(re.compile('x'), 0) if c.dtype == 'object' else c) Defensive patterns
Strategy: validation
Validate before calling
def safe_replace(df, to_replace, value):
# apply per column so each comparison is type-compatible
out = df.copy()
for col in out.columns:
try:
out[col] = out[col].replace(to_replace, value)
except TypeError:
continue
return out Try / catch
try:
df.replace(to_replace, value)
except TypeError as e:
if 'Cannot compare types' in str(e):
df.apply(lambda c: c.replace(to_replace, value) if c.dtype == 'object' else c)
else:
raise Prevention
- Apply replace per column for heterogeneous frames.
- Match the replacement value type to each column's dtype.
When it happens
Trigger: df.replace(non_comparable_value, new_value) where the value's type can't be compared to the column dtype (e.g. replacing a complex number in a string column); regex=False comparisons between incompatible types.
Common situations: Looping replace over heterogeneous columns with a single value list; passing None or an unsupported scalar type to replace on a numeric frame.
Related errors
- {cls_name} Expected type {cls}, found {type(left)} instead
- {op.__name__} not implemented for {type(other)}
- Lengths must match.
- Unordered Categoricals can only compare equality or not
- Categoricals can only be compared if 'categories' are the sa
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/b252ff12cba3062f.
Report an issue: GitHub.