{"record":{"id":"06b7cf4999aca2cf","repo":"pandas-dev/pandas","slug":"unable-to-avoid-copy-while-creating-an-array-as-re-06b7cf","errorCode":null,"errorMessage":"Unable to avoid copy while creating an array as requested.","messagePattern":"Unable to avoid copy while creating an array as requested\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/sparse/array.py","lineNumber":588,"sourceCode":"\n        return cls._simple_new(arr, index, dtype)\n\n    def __array__(\n        self, dtype: NpDtype | None = None, copy: bool | None = None\n    ) -> np.ndarray:\n        if self.sp_index.ngaps == 0:\n            # Compat for na dtype and int values.\n            if copy is True:\n                return np.array(self.sp_values)\n            else:\n                result = self.sp_values\n                if self._readonly:\n                    result = result.view()\n                    result.flags.writeable = False\n                return result\n\n        if copy is False:\n            raise ValueError(\n                \"Unable to avoid copy while creating an array as requested.\"\n            )\n\n        fill_value = self.fill_value\n\n        if dtype is None:\n            # Can NumPy represent this type?\n            # If not, `np.result_type` will raise. We catch that\n            # and return object.\n            if self.sp_values.dtype.kind == \"M\":\n                # However, we *do* special-case the common case of\n                # a datetime64 with pandas NaT.\n                if fill_value is NaT:\n                    # Can't put pd.NaT in a datetime64[ns]\n                    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))","sourceCodeStart":570,"sourceCodeEnd":606,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/sparse/array.py#L570-L606","documentation":"Raised by SparseArray.__array__ when copy=False is requested but the array has gaps (sp_index.ngaps > 0). Returning sp_values without copying would lose the fill-value positions, so a no-copy materialization is impossible.","triggerScenarios":"np.asarray(sparse_arr, copy=False) on a SparseArray with at least one fill_value gap; passing the array into a NumPy function that requests copy=False via the NEP 50 __array__ protocol.","commonSituations":"Performance-minded code trying to avoid copies; library internals that probe copy=False; upgrading numpy which now propagates copy= into __array__.","solutions":["Allow the copy: np.asarray(sparse_arr) or np.asarray(sparse_arr, copy=True).","Operate on .sp_values directly when you only need the non-fill entries.","If you must avoid the copy, work with a 0-gap array (no fill values present)."],"exampleFix":"# before\nnp.asarray(sparse_arr, copy=False)  # has gaps\n# after\nnp.asarray(sparse_arr)  # materializes dense, copying fill_value into place","handlingStrategy":"fallback","validationCode":"def can_avoid_copy(sparse_arr) -> bool:\n    return sparse_arr.sp_index.ngaps == 0","typeGuard":"def zero_gap_sparse(sparse_arr) -> bool:\n    return getattr(sparse_arr.sp_index, 'ngaps', 1) == 0","tryCatchPattern":"try:\n    arr = np.asarray(sparse_arr, copy=False)\nexcept ValueError as e:\n    if 'Unable to avoid copy' in str(e):\n        arr = np.asarray(sparse_arr)  # accept the copy\n    else:\n        raise","preventionTips":["Default to np.asarray(arr) without copy=False unless you measured a need.","Operate on .sp_values when you only need non-fill entries.","Document that SparseArray with gaps always requires a copy on dense materialization."],"tags":["pandas","sparse","numpy","copy"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}