pandas-dev/pandas · error · NotImplementedError
groupby first/last only supports 1D ExtensionArrays
Error message
groupby first/last only supports 1D ExtensionArrays
What it means
ExtensionArray._groupby_first_last (base.py:3208) only handles 1-D arrays; if self.ndim != 1 it raises NotImplementedError. The optimized first/last algorithm relies on per-group index lookup that is inherently 1-D.
Source
Thrown at pandas/core/arrays/base.py:3208
def _groupby_first_last(
self,
*,
how: str,
min_count: int,
ngroups: int,
ids: npt.NDArray[np.intp],
skipna: bool = True,
) -> Self:
"""
Optimized implementation of groupby first/last for ExtensionArrays.
Uses an index-based approach: computes the index of the first/last
non-NA element per group, then gathers results via take(). This avoids
any dtype conversion and works for all EA types.
"""
if self.ndim != 1:
raise NotImplementedError(
"groupby first/last only supports 1D ExtensionArrays"
)
isna_mask = np.asarray(self.isna(), dtype=np.uint8)
result_indices, result_mask = libgroupby.group_first_last_indexer(
labels=ids,
mask=isna_mask,
ngroups=ngroups,
skipna=skipna,
is_last=(how == "last"),
)
# Apply min_count: require at least min_count non-NA observations.
# For first/last, the natural minimum is 1 (need at least one value).
if min_count > 1:
nobs = np.zeros(ngroups, dtype=np.int64)
non_na_indices = np.where((~isna_mask.view(bool)) & (ids >= 0))[0]
np.add.at(nobs, ids[non_na_indices], 1)View on GitHub (pinned to 71959b8cb9)
Solutions
- Ensure the ExtensionArray is 1-D (ndim == 1) before groupby first/last.
- Flatten or split a multi-dimensional EA into 1-D arrays/Series.
- Override _groupby_first_last in your subclass if you genuinely need N-D handling.
- Fall back to a non-optimized path via apply() if N-D semantics are required.
Example fix
# before: custom EA with ndim == 2 hits first/last dispatch
# raises 'groupby first/last only supports 1D ExtensionArrays'
# after
for col in range(ea.shape[1]):
ea_1d = ea[:, col] # split into 1-D
... # then groupby first/last Defensive patterns
Strategy: validation
Validate before calling
def ensure_1d_ea(arr):
import numpy as np
if arr.ndim != 1:
raise ValueError(f"expected 1D EA, got ndim={arr.ndim}")
return arr Type guard
def is_1d(arr) -> bool:
return getattr(arr, "ndim", 1) == 1 Try / catch
try:
grouped = grouped_obj.first()
except NotImplementedError as e:
if "only supports 1D" in str(e):
# flatten or split N-D EA first
grouped = [arr[:, i] for i in range(arr.shape[1])]
else:
raise Prevention
- Keep ExtensionArrays 1-D for groupby first/last
- Flatten N-D EAs before groupby
- Override _groupby_first_last for custom N-D EAs
When it happens
Trigger: Triggered internally when pandas dispatches groupby first/last to an ExtensionArray whose ndim is not 1 (e.g. a multi-dimensional EA). Mostly an implementer/internal path; ordinary 1-D Series/columns never hit this.
Common situations: A custom ExtensionArray that is genuinely multi-dimensional (ndim>1) being used in a groupby first/last context; experimental stacked-array extensions.
Related errors
- Default 'empty' implementation is invalid for dtype='{dtype}
- function is not implemented for this dtype: {self.dtype}
- numpy operations are not valid with groupby. Use .groupby(..
- Array with ndim > 2 is not supported.
- cannot diff {type(arr).__name__} on axis={axis}
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/e71dff4725e9d291.
Report an issue: GitHub.