{"record":{"id":"b4736fa7079a3734","repo":"pandas-dev/pandas","slug":"sparsearray-does-not-support-in-place-sort","errorCode":null,"errorMessage":"SparseArray does not support in-place sort","messagePattern":"SparseArray does not support in-place sort","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/sparse/array.py","lineNumber":630,"sourceCode":"        return out\n\n    def __setitem__(self, key, value) -> None:\n        if self._readonly:\n            raise ValueError(\"Cannot modify read-only array\")\n        # I suppose we could allow setting of non-fill_value elements.\n        # TODO(SparseArray.__setitem__): remove special cases in\n        # ExtensionBlock.where\n        msg = \"SparseArray does not support item assignment via setitem\"\n        raise TypeError(msg)\n\n    def sort(\n        self,\n        *,\n        ascending: bool = True,\n        kind: SortKind = \"quicksort\",\n        na_position: str = \"last\",\n    ) -> None:\n        raise NotImplementedError(\"SparseArray does not support in-place sort\")\n\n    @classmethod\n    def _from_sequence(\n        cls, scalars, *, dtype: Dtype | None = None, copy: bool = False\n    ) -> Self:\n        return cls(scalars, dtype=dtype)\n\n    @classmethod\n    def _from_factorized(cls, values, original) -> Self:\n        return cls(values, dtype=original.dtype)\n\n    def _cast_pointwise_result(self, values):\n        if not (isinstance(values, np.ndarray) and values.dtype == object):\n            values = construct_1d_object_array_from_listlike(values)\n        result = lib.maybe_convert_objects(values, convert_non_numeric=True)\n        if result.dtype.kind == self.dtype.kind:\n            try:\n                # e.g. test_groupby_agg_extension","sourceCodeStart":612,"sourceCodeEnd":648,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/sparse/array.py#L612-L648","documentation":"SparseArray.sort() is declared to satisfy the ExtensionArray/NDArrayLike sort interface but always raises NotImplementedError. Sorting a sparse layout in place would be O(n) in the dense size and invalidate the sparse index, so it is intentionally unsupported.","triggerScenarios":"Calling arr.sort(...) directly on a SparseArray, or code that dispatches np.ndarray-style sort to an ExtensionArray (some groupby/sort_values internals).","commonSituations":"Generic helper code that calls .sort() on any array-like; switching a pipeline from numpy arrays to SparseArray expecting the same sort API.","solutions":["Sort the dense equivalent: sorted_vals = np.sort(np.asarray(arr)); rebuild SparseArray if needed.","Use pd.Series(arr).sort_values().values to get an ordered sparse-backed Series.","Guard callers with isinstance(arr, SparseArray) and route to a dense sort path."],"exampleFix":"// before\narr.sort()  # raises NotImplementedError\n// after\nordered = pd.Series(arr).sort_values()\narr = pd.arrays.SparseArray(ordered.to_numpy())","handlingStrategy":"type-guard","validationCode":"from pandas.core.arrays.sparse import SparseArray\n\ndef safe_sort(arr, **kw):\n    if isinstance(arr, SparseArray):\n        import numpy as np\n        return pd.arrays.SparseArray(np.sort(np.asarray(arr)))\n    return np.sort(arr, **kw) if hasattr(arr, 'sort') else sorted(arr)","typeGuard":"def needs_dense_sort(arr) -> bool:\n    from pandas.core.arrays.sparse import SparseArray\n    return isinstance(arr, SparseArray)","tryCatchPattern":"try:\n    arr.sort()\nexcept NotImplementedError as e:\n    if \"in-place sort\" in str(e):\n        import numpy as np\n        arr = pd.arrays.SparseArray(np.sort(np.asarray(arr)))\n    else:\n        raise","preventionTips":["Sort sparse data via Series.sort_values or np.sort on dense materialization.","Guard generic sort helpers with isinstance checks for SparseArray."],"tags":["sparse","sort","not-implemented","extension-array"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}