pandas-dev/pandas · error · TypeError
cannot subtract {type(self).__name__} from {type(other).__na
Error message
cannot subtract {type(self).__name__} from {type(other).__name__}[{other.dtype}] What it means
Raised by __rsub__ when self.dtype.kind == 'M' (DatetimeArray) and the left operand other has a dtype but is not itself datelike. Reflected subtraction (other - DatetimeArray) is only defined for datelike left operands; anything else (numeric, object) is rejected with a message that includes other's dtype.
Source
Thrown at pandas/core/arrays/datetimelike.py:1452
other_dtype, DatetimeTZDtype
)
if other_is_dt64 and lib.is_np_dtype(self.dtype, "m"):
# ndarray[datetime64] cannot be subtracted from self, so
# we need to wrap in DatetimeArray/Index and flip the operation
if lib.is_scalar(other):
# i.e. np.datetime64 object
return Timestamp(other) - self
if not isinstance(other, DatetimeLikeArrayMixin):
# Avoid down-casting DatetimeIndex
from pandas.core.arrays import DatetimeArray
other = DatetimeArray._from_sequence(other, dtype=other.dtype)
return other - self
elif self.dtype.kind == "M" and hasattr(other, "dtype") and not other_is_dt64:
# GH#19959 datetime - datetime is well-defined as timedelta,
# but any other type - datetime is not well-defined.
raise TypeError(
f"cannot subtract {type(self).__name__} from "
f"{type(other).__name__}[{other.dtype}]"
)
elif isinstance(self.dtype, PeriodDtype) and lib.is_np_dtype(other_dtype, "m"):
# TODO: Can we simplify/generalize these cases at all?
raise TypeError(f"cannot subtract {type(self).__name__} from {other.dtype}")
elif lib.is_np_dtype(self.dtype, "m"):
self = cast("TimedeltaArray", self)
return (-self) + other
flipped = self - other
if flipped.dtype.kind == "M":
# GH#59571 give a more helpful exception message
raise TypeError(
f"cannot subtract {type(self).__name__} from {type(other).__name__}"
)
# We get here with e.g. datetime objects
return -flippedView on GitHub (pinned to 71959b8cb9)
Solutions
- Reorder the expression so the DatetimeArray is on the left, or convert the left operand to a Timestamp.
- Cast the numeric operand to a timedelta if a duration was intended: pd.Timedelta(...) - datetime_idx is still invalid — flip to datetime_idx - pd.Timedelta(...).
- Convert the DatetimeArray to int64 ordinals before numeric subtraction: datetime_idx.astype('int64').
- Validate the left operand's dtype is datetime-like before reflected subtraction.
Example fix
// before out = 0 - datetime_idx # TypeError: cannot subtract DatetimeArray from ndarray[int64] // after out = datetime_idx - datetime_idx[0] # yields TimedeltaIndex
Defensive patterns
Strategy: validation
Validate before calling
from pandas.api.types import is_datetime64_any_dtype
if not (isinstance(other, (pd.Timestamp, pd.DatetimeIndex)) or is_datetime64_any_dtype(getattr(other, 'dtype', None))):
raise TypeError('left operand must be datelike for reflected subtraction from DatetimeArray') Type guard
def valid_rsub_left(other) -> bool:
from pandas.api.types import is_datetime64_any_dtype
return isinstance(other, (pd.Timestamp, pd.DatetimeIndex)) or is_datetime64_any_dtype(getattr(other, 'dtype', None)) Try / catch
try:
out = other - datetime_idx
except TypeError as e:
if 'cannot subtract' in str(e):
out = datetime_idx - other # flip to direct op
else:
raise Prevention
- Avoid reflected subtraction (other - DatetimeArray) with non-datetike left operands.
- Put the DatetimeArray on the left side of the expression.
- Validate the left operand's dtype before reflected subtraction.
When it happens
Trigger: np.array([1,2,3]) - datetime_idx, or int_series - DatetimeIndex, dispatched to __rsub__ at line 1431; the branch at line 1449 fires because other_is_dt64 is False.
Common situations: Reversed arithmetic in expressions like 0 - df['timestamp']; numpy broadcasting a scalar across a DatetimeIndex; mis-typed join keys.
Related errors
- cannot subtract a datelike from a {type(self).__name__}
- cannot subtract {type(self).__name__} from {type(other).__na
- cannot subtract {type(self).__name__} from {other.dtype}
- [datetimelike_compat=True] {left._values} is not equal to {r
- overflow in timedelta operation
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/421af7c50f81d520.
Report an issue: GitHub.