pandas-dev/pandas · error · NotImplementedError

SparseArray does not support in-place sort

Error message

SparseArray does not support in-place sort

What it means

Raised unconditionally (NotImplementedError) by SparseArray.sort. In-place sorting would reorder sp_values relative to sp_index in a way the storage format cannot express cheaply, so pandas refuses. Sorting must produce a new object.

Source

Thrown at pandas/core/arrays/sparse/array.py:625

        return out

    def __setitem__(self, key, value) -> None:
        if self._readonly:
            raise ValueError("Cannot modify read-only array")
        # I suppose we could allow setting of non-fill_value elements.
        # TODO(SparseArray.__setitem__): remove special cases in
        # ExtensionBlock.where
        msg = "SparseArray does not support item assignment via setitem"
        raise TypeError(msg)

    def sort(
        self,
        *,
        ascending: bool = True,
        kind: SortKind = "quicksort",
        na_position: str = "last",
    ) -> None:
        raise NotImplementedError("SparseArray does not support in-place sort")

    @classmethod
    def _from_sequence(
        cls, scalars, *, dtype: Dtype | None = None, copy: bool = False
    ) -> Self:
        return cls(scalars, dtype=dtype)

    @classmethod
    def _from_factorized(cls, values, original) -> Self:
        return cls(values, dtype=original.dtype)

    def _cast_pointwise_result(self, values):
        if not (isinstance(values, np.ndarray) and values.dtype == object):
            values = construct_1d_object_array_from_listlike(values)
        result = lib.maybe_convert_objects(values, convert_non_numeric=True)
        if result.dtype.kind == self.dtype.kind:
            try:
                # e.g. test_groupby_agg_extension

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Use numpy sort and rebuild: idx = np.argsort(arr.to_dense()); sorted_arr = arr.take(idx).
  2. Sort at the Series level: sorted_s = pd.Series(arr).sort_values().
  3. Avoid .sort(); use take() with a precomputed order.

Example fix

// before
arr.sort()
// after
order = np.argsort(arr.to_dense())
arr = arr.take(order)
Defensive patterns

Strategy: fallback

Validate before calling

import numpy as np

def sort_sparse(arr, ascending=True):
    dense = arr.to_dense()
    order = np.argsort(dense)
    if not ascending:
        order = order[::-1]
    return arr.take(order)

Type guard

def supports_inplace_sort(arr) -> bool:
    return type(arr).__name__ != 'SparseArray'

Try / catch

try:
    arr.sort()
except NotImplementedError as e:
    if 'in-place sort' in str(e):
        order = np.argsort(arr.to_dense())
        arr = arr.take(order)
    else:
        raise

Prevention

When it happens

Trigger: sparse_arr.sort(); arr.sort(ascending=False); calls from generic code that calls .sort() on any ExtensionArray.

Common situations: Generic algorithms that dispatch to .sort() on extension arrays; migrating dense sort code; trying to order a sparse column in place.

Related errors


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