{"record":{"id":"a7663c5c7ce63cd7","repo":"pandas-dev/pandas","slug":"period-type-does-not-support-how-operations","errorCode":null,"errorMessage":"Period type does not support {how} operations","messagePattern":"Period type does not support (.+?) operations","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/datetimelike.py","lineNumber":1644,"sourceCode":"        ids: npt.NDArray[np.intp],\n        **kwargs,\n    ):\n        dtype = self.dtype\n        if dtype.kind == \"M\":\n            # Adding/multiplying datetimes is not valid\n            if how in [\"sum\", \"prod\", \"cumsum\", \"cumprod\", \"var\", \"skew\", \"kurt\"]:\n                raise TypeError(f\"datetime64 type does not support operation '{how}'\")\n            if how in [\"any\", \"all\"]:\n                # GH#34479\n                raise TypeError(\n                    f\"'{how}' with datetime64 dtypes is no longer supported. \"\n                    f\"Use (obj != pd.Timestamp(0)).{how}() instead.\"\n                )\n\n        elif isinstance(dtype, PeriodDtype):\n            # Adding/multiplying Periods is not valid\n            if how in [\"sum\", \"prod\", \"cumsum\", \"cumprod\", \"var\", \"skew\", \"kurt\"]:\n                raise TypeError(f\"Period type does not support {how} operations\")\n            if how in [\"any\", \"all\"]:\n                # GH#34479\n                raise TypeError(\n                    f\"'{how}' with PeriodDtype is no longer supported. \"\n                    f\"Use (obj != pd.Period(ordinal=0, freq=freq)).{how}() instead.\"\n                )\n        # timedeltas we can add but not multiply\n        elif how in [\"prod\", \"cumprod\", \"skew\", \"kurt\", \"var\"]:\n            raise TypeError(f\"timedelta64 type does not support {how} operations\")\n\n        # All of the functions implemented here are ordinal, so we can\n        #  operate on the tz-naive equivalents\n        npvalues = self._ndarray.view(\"M8[ns]\")\n\n        from pandas.core.groupby.ops import WrappedCythonOp\n\n        kind = WrappedCythonOp.get_kind_from_how(how)\n        op = WrappedCythonOp(how=how, kind=kind, has_dropped_na=has_dropped_na)","sourceCodeStart":1626,"sourceCodeEnd":1662,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/datetimelike.py#L1626-L1662","documentation":"Raised inside DatetimeLikeArrayMixin._groupby_op when the underlying dtype is a PeriodDtype and the requested reduction 'how' is one of sum, prod, cumsum, cumprod, var, skew, or kurt. Periods represent ordinal positions on a fixed calendar grid; summing or multiplying them (or computing moments like variance/skew) has no defined meaning, so pandas refuses rather than producing a misleading numeric result.","triggerScenarios":"Calling groupby(...).sum()/.prod()/.cumsum()/.var()/.skew()/.kurt() (or DataFrame/Series reductions routed through the cython groupby engine) on a Series whose dtype is period[...] or a PeriodIndex; equivalently resample/rolling aggregations that map onto those how values over Period data.","commonSituations":"Loading monthly/quarterly data as Period columns and then running describe-style aggregations; migrating code from object/integer encodings to Period dtype and forgetting to strip it before summing; aggregating Period columns inside a groupby pipeline.","solutions":["Cast the Period column to a timestamp with .dt.to_timestamp() before the aggregation if you actually want time arithmetic.","If you need a count-like reduction, use size() or count() instead of sum().","Convert the Period to its ordinal integer via .astype('int64') (view of the underlying ordinal) if you intentionally want raw ordinal arithmetic.","Drop the Period dtype (e.g. .astype(str) or .dt.to_timestamp()) before applying sum/prod/etc."],"exampleFix":"// before\ns = pd.Series(pd.PeriodIndex(['2020-01','2020-02'], freq='M'), name='p')\ns.sum()  # TypeError: Period type does not support sum operations\n\n// after\ns.dt.to_timestamp().sum()  # or s.groupby(key).size() for counts","handlingStrategy":"validation","validationCode":"def safe_period_groupby(s, how):\n    if pd.api.types.is_period_dtype(s):\n        if how in {\"sum\",\"prod\",\"cumsum\",\"cumprod\",\"var\",\"skew\",\"kurt\"}:\n            raise ValueError(f\"{how} is unsupported on Period; convert to timestamp first\")\n    return s.groupby(level=0) if isinstance(s, pd.Series) else s","typeGuard":"def is_period_reduction_unsupported(dtype, how) -> bool:\n    return isinstance(dtype, pd.PeriodDtype) and how in {\"sum\",\"prod\",\"cumsum\",\"cumprod\",\"var\",\"skew\",\"kurt\"}","tryCatchPattern":"try:\n    result = s.groupby(g).sum()\nexcept TypeError as e:\n    if \"Period type does not support\" in str(e):\n        result = s.dt.to_timestamp().groupby(g).sum()\n    else:\n        raise","preventionTips":["Centralize groupby aggregations behind a helper that branches on dtype.kind / PeriodDtype.","Document Period columns explicitly in schemas so consumers know not to sum them.","Add unit tests that assert a TypeError for unsupported period reductions."],"tags":["pandas","period","groupby","dtype","reduction"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}