{"record":{"id":"98723d3e3711ddbb","repo":"pandas-dev/pandas","slug":"cumprod-not-supported-for-timedelta","errorCode":null,"errorMessage":"cumprod not supported for Timedelta.","messagePattern":"cumprod not supported for Timedelta\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/timedeltas.py","lineNumber":427,"sourceCode":"            (), {\"dtype\": dtype, \"out\": out, \"keepdims\": keepdims}, fname=\"std\"\n        )\n\n        result = nanops.nanstd(self._ndarray, axis=axis, skipna=skipna, ddof=ddof)\n        if axis is None or self.ndim == 1:\n            return self._box_func(result)\n        return self._from_backing_data(result)\n\n    # ----------------------------------------------------------------\n    # Accumulations\n\n    def _accumulate(self, name: str, *, skipna: bool = True, **kwargs):\n        if name == \"cumsum\":\n            op = getattr(datetimelike_accumulations, name)\n            result = op(self._ndarray.copy(), skipna=skipna, **kwargs)\n\n            return type(self)._simple_new(result, dtype=self.dtype)\n        elif name == \"cumprod\":\n            raise TypeError(\"cumprod not supported for Timedelta.\")\n\n        else:\n            return super()._accumulate(name, skipna=skipna, **kwargs)\n\n    # ----------------------------------------------------------------\n    # Rendering Methods\n\n    def _formatter(self, boxed: bool = False):\n        from pandas.io.formats.format import get_format_timedelta64\n\n        return get_format_timedelta64(self, box=True)\n\n    def _format_native_types(\n        self, *, na_rep: str | float = \"NaT\", date_format=None, **kwargs\n    ) -> npt.NDArray[np.object_]:\n        from pandas.io.formats.format import get_format_timedelta64\n\n        # Relies on TimeDelta._repr_base","sourceCodeStart":409,"sourceCodeEnd":445,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/timedeltas.py#L409-L445","documentation":"Raised by TimedeltaArray._accumulate when name=='cumprod'. Cumulative product of timedeltas is not defined (multiplying two durations does not yield a duration), so pandas explicitly rejects it with a TypeError while allowing cumsum/cummin/cummax. This prevents meaningless operations from silently producing garbage.","triggerScenarios":"Calling `s.cumprod()`, `df.cumprod()`, or `.expanding().prod()` (via accumulation) on a timedelta64 Series/Index. The branch at timedeltas.py:427 raises for name=='cumprod'.","commonSituations":"Running generic .cumprod() over a whole DataFrame that includes duration columns; copy-paste from numeric pipelines; expecting time-arithmetic semantics that do not exist.","solutions":["Exclude timedelta columns before cumprod: `df.select_dtypes(exclude='timedelta').cumprod()`.","If you meant cumulative sum of durations, use .cumsum() which is supported.","If you need a product of magnitudes, operate on .dt.total_seconds() and re-wrap if meaningful."],"exampleFix":"# before\ns = pd.Series(pd.to_timedelta(['1s','2s','3s']))\ns.cumprod()  # TypeError\n# after\ns.cumsum()  # cumulative duration sum","handlingStrategy":"validation","validationCode":"import pandas as pd\n\ndef safe_cumprod(df):\n    numeric = df.select_dtypes(exclude='timedelta')\n    return numeric.cumprod()","typeGuard":"import pandas as pd\ndef is_not_timedelta(s) -> bool:\n    return not pd.api.types.is_timedelta64_dtype(s)","tryCatchPattern":"try:\n    return s.cumprod()\nexcept TypeError as e:\n    if 'cumprod not supported for Timedelta' in str(e):\n        return s.cumsum()\n    raise","preventionTips":["Exclude timedelta columns before .cumprod() on DataFrames.","Prefer .cumsum() for durations.","Add dtype-aware wrappers for generic accumulation pipelines."],"tags":["timedelta","cumprod","accumulation","typeerror"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}