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
- Convert dates to timestamps first: `s.astype("timestamp[us][pyarrow]").dt.as_unit("ms")`.
- If the column should be a duration, cast to a duration type before as_unit.
- Verify the dtype with `s.dtype` and ensure it is timestamp[pyarrow] or duration[pyarrow] before calling as_unit.
- 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
- Convert date types to timestamp[pyarrow] before as_unit.
- Document the supported dtype set for as_unit in shared temporal utilities.
- Validate dtype before rescaling in pipelines.
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
- ambiguous is not supported.
- nonexistent is not supported.
- {ambiguous=} is not supported
- {nonexistent=} is not supported
- replace is not supported with a re.Pattern, callable repl, c
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/913b6bed746dcdf7.
Report an issue: GitHub.