pandas-dev/pandas · error · TypeError

cannot subtract from

Error message

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

What it means

Raised in __rsub__ when self is a PeriodArray (PeriodDtype) and other is a numpy timedelta64. Subtracting a timedelta from a Period in the reflected direction is not defined the way it is for DatetimeArray, so pandas rejects it, reporting the PeriodArray type and the timedelta dtype.

Solutions

  1. Put the PeriodArray on the left: parr + timedelta or parr - timedelta are the supported directions.
  2. Convert the PeriodArray to timestamps via .to_timestamp() if you need datetime+timedelta semantics.
  3. Use Period arithmetic appropriate to the freq (e.g. shift by integer count of periods).

Example fix

// before
res = np.timedelta64(1, 'D') - parr  # TypeError

// after
res = parr + np.timedelta64(1, 'D')
Defensive patterns

Strategy: type-guard

Validate before calling

import pandas as pd, numpy as np

def rsub_period_safe(parr, other):
    if isinstance(parr.dtype, pd.PeriodDtype) and pd.api.types.is_timedelta64_dtype(getattr(other, 'dtype', None)):
        raise TypeError('timedelta - PeriodArray is undefined; reverse the operands')
    return other - parr

Type guard

import pandas as pd

def is_period_array(a) -> bool:
    return isinstance(getattr(a, 'dtype', None), pd.PeriodDtype)

Try / catch

try:
    res = other - parr
except TypeError as e:
    if 'cannot subtract' in str(e) and 'Period' in str(e):
        res = parr + other  # PeriodArray + timedelta is supported
    else:
        raise

Prevention

When it happens

Trigger: np.timedelta64(1,'D') - PeriodArray(...); timedelta64 Series - PeriodIndex; any reflected subtraction where a timedelta is on the left and a Period array on the right.

Common situations: Mixed Period/timedelta arithmetic in scheduling code; assuming Period + timedelta commutes the way datetime + timedelta does.

Related errors


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

Appendix: source

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

            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 3b7651241d)