pandas-dev/pandas · error · NotImplementedError

as_unit not implemented for {pa_type}

Error message

as_unit not implemented for {pa_type}

What it means

Raised by ArrowExtensionArray._dt_as_unit when the array's pyarrow type is neither a timestamp nor a duration. _dt_as_unit only knows how to rescale those two type families; any other type (date32/date64, int, string, etc.) hits the else branch with NotImplementedError. Reached through Series.dt.as_unit() on a pyarrow-backed datetime/timedelta-like Series.

Source

Thrown at pandas/core/arrays/arrow/array.py:3932

        data = self._pa_array.to_pylist()
        if self._dtype.pyarrow_dtype.unit == "ns":
            data = [None if ts is None else ts.to_pytimedelta() for ts in data]
        return np.array(data, dtype=object)

    def _dt_total_seconds(self) -> Self:
        unit = self._pa_array.type.unit
        unit_per_second = {"s": 1.0, "ms": 1e3, "us": 1e6, "ns": 1e9}
        result = pc.divide(pc.cast(self._pa_array, pa.int64()), unit_per_second[unit])
        return self._from_pyarrow_array(result)

    def _dt_as_unit(self, unit: str) -> Self:
        pa_type = self._pa_array.type
        if pa.types.is_timestamp(pa_type):
            target_type = pa.timestamp(unit, tz=pa_type.tz)
        elif pa.types.is_duration(pa_type):
            target_type = pa.duration(unit)
        else:
            raise NotImplementedError(f"as_unit not implemented for {pa_type}")

        nanos_per_unit = {"s": 1_000_000_000, "ms": 1_000_000, "us": 1_000, "ns": 1}
        from_nanos = nanos_per_unit[pa_type.unit]
        to_nanos = nanos_per_unit[unit]
        if to_nanos <= from_nanos:
            # Same or finer resolution: exact upscale. Use safe=True so that
            # out-of-bounds values raise instead of silently wrapping, matching
            # numpy/pandas as_unit.
            try:
                result = pc.cast(self._pa_array, target_type)
            except pa.ArrowInvalid as err:
                err_type = (
                    OutOfBoundsDatetime
                    if pa.types.is_timestamp(pa_type)
                    else OutOfBoundsTimedelta
                )
                raise err_type(
                    f"Cannot convert {pa_type} to {target_type} without overflow"

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Convert dates to timestamps first: `s.astype("timestamp[us][pyarrow]").dt.as_unit("ms")`.
  2. If the column should be a duration, cast to a duration type before as_unit.
  3. Verify the dtype with `s.dtype` and ensure it is timestamp[pyarrow] or duration[pyarrow] before calling as_unit.
  4. Use `.astype("datetime64[ns]")` then `.dt.as_unit(...)` if you want the numpy-backed path.

Example fix

# before
s = pd.Series(pd.to_datetime(["2024-01-01"]).date, dtype="date32[pyarrow]")
s.dt.as_unit("ms")  # NotImplementedError

# after
s.astype("timestamp[us][pyarrow]").dt.as_unit("ms")
Defensive patterns

Strategy: validation

Validate before calling

import pyarrow as pa

def can_as_unit(s) -> bool:
    pa_dt = getattr(s.dtype, "pyarrow_dtype", None)
    return pa_dt is not None and (pa.types.is_timestamp(pa_dt) or pa.types.is_duration(pa_dt))

def safe_as_unit(s, unit):
    if not can_as_unit(s):
        raise NotImplementedError(f"dt.as_unit needs timestamp/duration pyarrow dtype, got {s.dtype}")
    return s.dt.as_unit(unit)

Type guard

import pyarrow as pa

def is_temporal_rescalable(s) -> bool:
    pa_dt = getattr(s.dtype, "pyarrow_dtype", None)
    return pa_dt is not None and (pa.types.is_timestamp(pa_dt) or pa.types.is_duration(pa_dt))

Try / catch

try:
    out = s.dt.as_unit(unit)
except NotImplementedError:
    out = s.astype("timestamp[us][pyarrow]").dt.as_unit(unit)

Prevention

When it happens

Trigger: Calling `s.dt.as_unit("ms")` on a Series whose dtype is `date32[pyarrow]`, `date64[pyarrow]`, or a non-temporal pyarrow type that happens to expose a `.dt` accessor (rare). Date types have no sub-day resolution to convert.

Common situations: Treating a date column as if it had a time unit; loading Arrow data where dates (not timestamps) were stored; trying to normalize units on a column before arithmetic that actually needs a timestamp.

Related errors


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