pandas-dev/pandas · error · IncompatibleFrequency
Cannot add/subtract timedelta-like from PeriodArray that is…
Error message
Cannot add/subtract timedelta-like from PeriodArray that is not an integer multiple of the PeriodArray's freq.
What it means
Raised by PeriodArray._time_shift when astype_overflowsafe cannot losslessly convert the timedelta operand into the period's timedelta unit (round_ok=False). The operation requires the delta to be an exact integer multiple of the period's tick; a sub-multiple (e.g. 30 seconds with a minute freq) cannot be represented and raises IncompatibleFrequency.
Solutions
- Round the delta to a whole multiple of the period: (delta // idx.freq) * idx.freq, then add.
- Switch to a finer period freq that the delta divides evenly (e.g. 's' instead of 'min').
- Quantize the timedelta to the period unit before adding: delta.round(idx.freq).
Example fix
# before
idx = pd.period_range('2023-01-01', periods=3, freq='min')
idx + pd.Timedelta('30s') # raises
# after
idx + pd.Timedelta('60s') # whole-minute delta
# or
idx.to_timestamp() + pd.Timedelta('30s') Defensive patterns
Strategy: validation
Validate before calling
import pandas as pd
def add_timedelta_to_period(period_idx, delta):
freq = period_idx.freq
delta = pd.Timedelta(delta)
n_periods = delta // pd.Timedelta(freq.nanos) if hasattr(freq, 'nanos') else None
if n_periods is None or delta != n_periods * pd.Timedelta(freq.nanos):
raise ValueError(f'{delta} is not an integer multiple of {freq}')
return period_idx + int(n_periods) * freq Type guard
import pandas as pd
def is_whole_period_multiple(delta, freq) -> bool:
try:
delta = pd.Timedelta(delta)
return delta == (delta // pd.Timedelta(freq.nanos)) * pd.Timedelta(freq.nanos)
except (ValueError, AttributeError, TypeError):
return False Try / catch
try:
period_idx + delta
except Exception as e: # IncompatibleFrequency subclasses ValueError
if 'integer multiple' in str(e):
delta = (pd.Timedelta(delta) // pd.Timedelta(period_idx.freq.nanos)) * period_idx.freq
period_idx + delta
else:
raise Prevention
- Round sub-period timedeltas to whole multiples of idx.freq before adding.
- Prefer integer period offsets (n * idx.freq) over raw Timedeltas for period arithmetic.
- Drop to tick-like freq (e.g. 'min'->'s') when sub-period resolution is required.
When it happens
Trigger: minute_idx + pd.Timedelta('30s') — 30s is half a minute. daily_idx + np.timedelta64(12, 'h') — 12h is not a whole day. hourly_idx + pd.Timedelta('90s') where 90s doesn't divide the hour evenly into the array's unit.
Common situations: Sub-period deltas from sensor/IoT data; rounding errors in computed Timedeltas; mixing freq units (minutes + seconds) without alignment.
Related errors
- Cannot add or subtract timedelta64[ns] dtype from
- specified freq and dtype are different
- Could not infer freq from start/end
- dtype is not specified and cannot be inferred
- freq must be a quarterly frequency
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/8fcc3d84bd356ebb.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/arrays/period.py:1283
"""
if not self.dtype._is_tick_like():
# We cannot add timedelta-like to non-tick PeriodArray
raise TypeError(
f"Cannot add or subtract timedelta64[ns] dtype from {self.dtype}"
)
dtype = np.dtype(f"m8[{self.dtype._td64_unit}]")
# Similar to _check_timedeltalike_freq_compat, but we raise with a
# more specific exception message if necessary.
try:
delta = astype_overflowsafe(
np.asarray(other), dtype=dtype, copy=False, round_ok=False
)
except ValueError as err:
# e.g. if we have minutes freq and try to add 30s
# "Cannot losslessly convert units"
raise IncompatibleFrequency(
"Cannot add/subtract timedelta-like from PeriodArray that is "
"not an integer multiple of the PeriodArray's freq."
) from err
res_values = add_overflowsafe(self.asi8, np.asarray(delta.view("i8")))
return type(self)(res_values, dtype=self.dtype)
def _check_timedeltalike_freq_compat(self, other):
"""
Arithmetic operations with timedelta-like scalars or array `other`
are only valid if `other` is an integer multiple of `self.freq`.
If the operation is valid, find that integer multiple. Otherwise,
raise because the operation is invalid.
Parameters
----------
other : timedelta, np.timedelta64, Tick,
ndarray[timedelta64], TimedeltaArray, TimedeltaIndexView on GitHub (pinned to 3b7651241d)