{"record":{"id":"4aacd4bccce657dc","repo":"pandas-dev/pandas","slug":"sparsearray-does-not-support-item-assignment-via-s","errorCode":null,"errorMessage":"SparseArray does not support item assignment via setitem","messagePattern":"SparseArray does not support item assignment via setitem","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/sparse/array.py","lineNumber":616,"sourceCode":"                    unit = np.datetime_data(self.sp_values.dtype)[0]\n                    fill_value = np.datetime64(\"NaT\", unit)  # type: ignore[call-overload]\n            try:\n                dtype = np.result_type(self.sp_values.dtype, type(fill_value))\n            except TypeError:\n                dtype = object\n\n        out = np.full(self.shape, fill_value, dtype=dtype)\n        out[self.sp_index.indices] = self.sp_values\n        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:","sourceCodeStart":598,"sourceCodeEnd":634,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/sparse/array.py#L598-L634","documentation":"Raised unconditionally in SparseArray.__setitem__ (after the read-only check). SparseArray does not support in-place item assignment at all because updating a single value would require re-deriving the sparse index (sp_values + sp_index), so every setitem is rejected with TypeError. The supported path is to build a new array.","triggerScenarios":"sparse_arr[0] = 5; sparse_arr[i] = value in a loop; df['col'] = ... where df['col'].array is a SparseArray and code tries positional writes through .array.","commonSituations":"Porting dense ndarray/Series code that mutates positions; vectorized fills written as loops; trying to patch a few entries in a sparse column.","solutions":["Rebuild the SparseArray from modified dense data: new = pd.arrays.SparseArray(np.where(mask, value, arr.to_dense())).","Operate at the Series level with .fillna/.where/.mask which return new objects.","If you only need to fill NAs, use arr.fillna(value) instead of setitem."],"exampleFix":"// before\narr[2] = 99\n// after\ndense = arr.to_dense(); dense[2] = 99; arr = pd.arrays.SparseArray(dense, dtype=arr.dtype)","handlingStrategy":"fallback","validationCode":"import pandas as pd\nimport numpy as np\n\ndef assign_sparse(arr, mask, value):\n    dense = arr.to_dense()\n    dense = np.where(mask, value, dense)\n    return pd.arrays.SparseArray(dense, dtype=arr.dtype)","typeGuard":"def supports_setitem(arr) -> bool:\n    return type(arr).__name__ != 'SparseArray'","tryCatchPattern":"try:\n    arr[0] = value\nexcept TypeError as e:\n    if 'setitem' in str(e):\n        dense = arr.to_dense(); dense[0] = value\n        arr = pd.arrays.SparseArray(dense, dtype=arr.dtype)\n    else:\n        raise","preventionTips":["Never use __setitem__ on SparseArray; rebuild instead.","Use Series.fillna/.where/.mask for value replacement.","Document immutability in code that exposes SparseArray."],"tags":["pandas","sparse","sparse-array","setitem","immutable"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}