{"record":{"id":"913b6bed746dcdf7","repo":"pandas-dev/pandas","slug":"as-unit-not-implemented-for-pa-type","errorCode":null,"errorMessage":"as_unit not implemented for {pa_type}","messagePattern":"as_unit not implemented for (.+?)","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/arrow/array.py","lineNumber":3960,"sourceCode":"        data = self._pa_array.to_pylist()\n        if self._dtype.pyarrow_dtype.unit == \"ns\":\n            data = [None if ts is None else ts.to_pytimedelta() for ts in data]\n        return np.array(data, dtype=object)\n\n    def _dt_total_seconds(self) -> Self:\n        unit = self._pa_array.type.unit\n        unit_per_second = {\"s\": 1.0, \"ms\": 1e3, \"us\": 1e6, \"ns\": 1e9}\n        result = pc.divide(pc.cast(self._pa_array, pa.int64()), unit_per_second[unit])\n        return self._from_pyarrow_array(result)\n\n    def _dt_as_unit(self, unit: str) -> Self:\n        pa_type = self._pa_array.type\n        if pa.types.is_timestamp(pa_type):\n            target_type = pa.timestamp(unit, tz=pa_type.tz)\n        elif pa.types.is_duration(pa_type):\n            target_type = pa.duration(unit)\n        else:\n            raise NotImplementedError(f\"as_unit not implemented for {pa_type}\")\n\n        nanos_per_unit = {\"s\": 1_000_000_000, \"ms\": 1_000_000, \"us\": 1_000, \"ns\": 1}\n        from_nanos = nanos_per_unit[pa_type.unit]\n        to_nanos = nanos_per_unit[unit]\n        if to_nanos <= from_nanos:\n            # Same or finer resolution: exact upscale. Use safe=True so that\n            # out-of-bounds values raise instead of silently wrapping, matching\n            # numpy/pandas as_unit.\n            try:\n                result = pc.cast(self._pa_array, target_type)\n            except pa.ArrowInvalid as err:\n                err_type = (\n                    OutOfBoundsDatetime\n                    if pa.types.is_timestamp(pa_type)\n                    else OutOfBoundsTimedelta\n                )\n                raise err_type(\n                    f\"Cannot convert {pa_type} to {target_type} without overflow\"","sourceCodeStart":3942,"sourceCodeEnd":3978,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/arrow/array.py#L3942-L3978","documentation":"Raised by ArrowExtensionArray._dt_as_unit when the array's pyarrow type is neither a timestamp nor a duration. `_dt_as_unit` reinterprets the value into a different unit (s/ms/us/ns) and only pyarrow timestamp and duration types carry a `unit`; any other type (date, time, int, etc.) is unsupported.","triggerScenarios":"Calling `ser.dt.as_unit('ms')` (via `.dt.as_unit`) on a pyarrow-backed Series whose dtype is not timestamp[pyarrow] or duration[pyarrow] — for example a date32[pyarrow] or time32[pyarrow] column.","commonSituations":"Calling `.dt.as_unit` on a date-typed arrow column expecting it to act like a timestamp; chaining after an operation that changed the dtype away from timestamp/duration.","solutions":["Cast the column to a pyarrow timestamp first: `ser.astype('timestamp[ms][pyarrow]')` then call `.dt.as_unit`.","Confirm the dtype with `ser.dtype` before calling `.dt.as_unit`; only proceed for timestamp/duration arrow dtypes."],"exampleFix":"# before\ndate_col.dt.as_unit('ms')      # date32[pyarrow]\n# after\ndate_col.astype('timestamp[ms][pyarrow]').dt.as_unit('ms')","handlingStrategy":"validation","validationCode":"import pyarrow as pa\nt = ser.dtype.pyarrow_dtype\nif not (pa.types.is_timestamp(t) or pa.types.is_duration(t)):\n    raise NotImplementedError(f\"as_unit not supported for {t}; cast to timestamp first\")\nser.dt.as_unit('ms')","typeGuard":"def supports_as_unit(ser) -> bool:\n    import pyarrow as pa\n    t = getattr(ser.dtype, \"pyarrow_dtype\", None)\n    return t is not None and (pa.types.is_timestamp(t) or pa.types.is_duration(t))","tryCatchPattern":"try:\n    out = ser.dt.as_unit('ms')\nexcept NotImplementedError as e:\n    if \"as_unit not implemented\" in str(e):\n        out = ser.astype('timestamp[ms][pyarrow]')\n    else:\n        raise","preventionTips":["Check pyarrow type is timestamp/duration before .dt.as_unit","Cast date columns to timestamp before unit conversion"],"tags":["pyarrow","datetime-accessor","not-implemented","arrow-extension"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}