pandas-dev/pandas · error · TypeError

mean is not implemented for {type(self).__name__} since the

Error message

mean is not implemented for {type(self).__name__} since the meaning is ambiguous.  An alternative is obj.to_timestamp(how='start').mean()

What it means

Raised by mean() when self.dtype is PeriodDtype (see GH#24757). Averaging absolute Period values is ambiguous because the choice of start vs end timestamp, and the freq anchor, changes the answer; pandas refuses and points the user at to_timestamp(how='start').mean().

Source

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

        >>> idx = pd.date_range("2001-01-01 00:00", periods=3)
        >>> idx
        DatetimeIndex(['2001-01-01', '2001-01-02', '2001-01-03'],
                      dtype='datetime64[us]', freq='D')
        >>> idx.mean()
        Timestamp('2001-01-02 00:00:00')

        For :class:`pandas.TimedeltaIndex`:

        >>> tdelta_idx = pd.to_timedelta([1, 2, 3], unit="D")
        >>> tdelta_idx
        TimedeltaIndex(['1 days', '2 days', '3 days'],
                        dtype='timedelta64[s]', freq=None)
        >>> tdelta_idx.mean()
        Timedelta('2 days 00:00:00')
        """
        if isinstance(self.dtype, PeriodDtype):
            # See discussion in GH#24757
            raise TypeError(
                f"mean is not implemented for {type(self).__name__} since the "
                "meaning is ambiguous.  An alternative is "
                "obj.to_timestamp(how='start').mean()"
            )

        result = nanops.nanmean(
            self._ndarray, axis=axis, skipna=skipna, mask=self.isna()
        )
        return self._wrap_reduction_result(axis, result)

    @_period_dispatch
    def median(self, *, axis: AxisInt | None = None, skipna: bool = True, **kwargs):
        nv.validate_median((), kwargs)

        if axis is not None and abs(axis) >= self.ndim:
            raise ValueError("abs(axis) must be less than ndim")

        result = nanops.nanmedian(self._ndarray, axis=axis, skipna=skipna)

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Convert to timestamp first as the message suggests: idx.to_timestamp(how='start').mean() (or how='end').
  2. For integer-meaningful aggregation, average the ordinals: int(idx.view('i8').mean()) then reconstruct a Period.
  3. If grouping, group on the Period column but aggregate a numeric column, not the Period itself.
  4. For resampling, use .to_timestamp() then resample and convert back with .to_period(freq).

Example fix

// before
m = period_idx.mean()  # TypeError: mean is not implemented
// after
m = period_idx.to_timestamp(how='start').mean()
Defensive patterns

Strategy: type-guard

Validate before calling

from pandas.api.types import is_period_dtype
if is_period_dtype(idx.dtype):
    m = idx.to_timestamp(how='start').mean()
else:
    m = idx.mean()

Type guard

def rejects_direct_mean(idx) -> bool:
    from pandas.api.types import is_period_dtype
    return is_period_dtype(idx.dtype)

Try / catch

try:
    m = idx.mean()
except TypeError as e:
    if 'mean is not implemented' in str(e):
        m = idx.to_timestamp(how='start').mean()
    else:
        raise

Prevention

When it happens

Trigger: Calling period_idx.mean() or period_series.mean(); dispatched into the EA mean override at line 1574; the PeriodDtype check at line 1574 raises.

Common situations: Resampling/aggregating Period-indexed data; porting DatetimeIndex pipelines to PeriodIndex; calling .describe() or .groupby().mean() on Period columns.

Related errors


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