pandas-dev/pandas · error · TypeError

cannot subtract {type(self).__name__} from {other.dtype}

Error message

cannot subtract {type(self).__name__} from {other.dtype}

What it means

Raised by __rsub__ when self.dtype is PeriodDtype and other has a timedelta (kind 'm') dtype. Subtracting a PeriodArray from a TimedeltaArray is not defined; the message reports other.dtype directly because the operation is only meaningful for PeriodArray - PeriodArray.

Source

Thrown at pandas/core/arrays/datetimelike.py:1458

            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 -flipped

    def __iadd__(self, other) -> Self:
        result = self + other
        self[:] = result[:]
        return self

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Convert the PeriodArray to Timestamps first: period_idx.to_timestamp(), then subtract.
  2. Flip the operation: period_idx - timedelta shift is also unsupported; use idx.shift(n) instead.
  3. Verify isinstance(left.dtype, pd.PeriodDtype) before performing reflected subtraction.
  4. If a duration result is needed, work in ordinal space: period_idx.astype('int64').

Example fix

// before
out = timedelta_idx - period_idx  # TypeError: cannot subtract PeriodArray from timedelta64[ns]
// after
out = period_idx.to_timestamp() - timedelta_idx
Defensive patterns

Strategy: type-guard

Validate before calling

from pandas.api.types import is_period_dtype, is_timedelta64_dtype
if is_period_dtype(idx.dtype) and is_timedelta64_dtype(getattr(other, 'dtype', None)):
    raise TypeError('cannot subtract PeriodArray from TimedeltaIndex; convert first')

Type guard

def rejects_period_rsub_from_td(other, idx) -> bool:
    from pandas.api.types import is_period_dtype, is_timedelta64_dtype
    return is_period_dtype(idx.dtype) and is_timedelta64_dtype(getattr(other, 'dtype', None))

Try / catch

try:
    out = timedelta_idx - period_idx
except TypeError as e:
    if 'cannot subtract' in str(e) and 'PeriodArray' in str(e):
        out = period_idx.to_timestamp() - timedelta_idx
    else:
        raise

Prevention

When it happens

Trigger: timedelta_idx - period_idx, dispatched to __rsub__ at line 1431; the branch at line 1456 fires.

Common situations: Mixed Period/Timedelta arithmetic; assuming PeriodIndex participates in duration subtraction on either side.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/ee5f7a11a968c4d4. Report an issue: GitHub.