{"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":625,"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":607,"sourceCodeEnd":643,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/sparse/array.py#L607-L643","documentation":"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.","triggerScenarios":"sparse_arr.sort(); arr.sort(ascending=False); calls from generic code that calls .sort() on any ExtensionArray.","commonSituations":"Generic algorithms that dispatch to .sort() on extension arrays; migrating dense sort code; trying to order a sparse column in place.","solutions":["Use numpy sort and rebuild: idx = np.argsort(arr.to_dense()); sorted_arr = arr.take(idx).","Sort at the Series level: sorted_s = pd.Series(arr).sort_values().","Avoid .sort(); use take() with a precomputed order."],"exampleFix":"// before\narr.sort()\n// after\norder = np.argsort(arr.to_dense())\narr = arr.take(order)","handlingStrategy":"fallback","validationCode":"import numpy as np\n\ndef sort_sparse(arr, ascending=True):\n    dense = arr.to_dense()\n    order = np.argsort(dense)\n    if not ascending:\n        order = order[::-1]\n    return arr.take(order)","typeGuard":"def supports_inplace_sort(arr) -> bool:\n    return type(arr).__name__ != 'SparseArray'","tryCatchPattern":"try:\n    arr.sort()\nexcept NotImplementedError as e:\n    if 'in-place sort' in str(e):\n        order = np.argsort(arr.to_dense())\n        arr = arr.take(order)\n    else:\n        raise","preventionTips":["Use take(np.argsort(...)) to sort SparseArray immutably.","Sort at the Series level with sort_values().","Don't dispatch generic .sort() to extension arrays."],"tags":["pandas","sparse","sparse-array","sort","not-implemented"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}