{"record":{"id":"9ac0ec49ddb907fe","repo":"pandas-dev/pandas","slug":"can-only-use-the-sparse-accessor-with-sparse-da","errorCode":null,"errorMessage":"Can only use the '.sparse' accessor with Sparse data.","messagePattern":"Can only use the '\\.sparse' accessor with Sparse data\\.","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/sparse/accessor.py","lineNumber":78,"sourceCode":"    See Also\n    --------\n    Series.sparse.to_coo : Create a scipy.sparse.coo_matrix from a Series with\n        MultiIndex.\n    Series.sparse.from_coo : Create a Series with sparse values from a\n        scipy.sparse.coo_matrix.\n\n    Examples\n    --------\n    >>> ser = pd.Series([0, 0, 2, 2, 2], dtype=\"Sparse[int]\")\n    >>> ser.sparse.density\n    0.6\n    >>> ser.sparse.sp_values\n    array([2, 2, 2])\n    \"\"\"\n\n    def _validate(self, data) -> None:\n        if not isinstance(data.dtype, SparseDtype):\n            raise AttributeError(self._validation_msg)\n\n    def _delegate_property_get(self, name: str, *args, **kwargs):\n        return getattr(self._parent.array, name)\n\n    def _delegate_method(self, name: str, *args, **kwargs):\n        if name == \"from_coo\":\n            return self.from_coo(*args, **kwargs)\n        elif name == \"to_coo\":\n            return self.to_coo(*args, **kwargs)\n        else:\n            raise ValueError\n\n    @classmethod\n    def from_coo(cls, A, dense_index: bool = False) -> Series:\n        \"\"\"\n        Create a Series with sparse values from a scipy.sparse.coo_matrix.\n\n        This method takes a ``scipy.sparse.coo_matrix`` (coordinate format) as input and","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/sparse/accessor.py#L60-L96","documentation":"Raised as AttributeError by SparseArrayAccessor (Series.sparse) _validate when the Series dtype is not SparseDtype. The .sparse accessor is registered only for sparse-backed Series; accessing it on a dense Series is a programming error.","triggerScenarios":"ser.sparse.density where ser = pd.Series([0,0,1]); any df['col'].sparse.* on a column cast back to dense; calling .sparse.from_coo on a non-sparse Series.","commonSituations":"Forgetting to cast dtype='Sparse[int]' or dtype='Sparse[float]'; downstream code that re-cast a sparse column to dense via .astype() or .values; chained operations that lost the dtype.","solutions":["Cast first: ser.astype('Sparse[int]') (or 'Sparse[float64, 0.0]') before using .sparse.","Check pd.api.types.is_sparse_dtype(ser.dtype) before accessing .sparse.","Preserve sparse dtype end-to-end in your pipeline."],"exampleFix":"# before\ns = pd.Series([0,0,1,2])\ns.sparse.density\n# after\ns = pd.Series([0,0,1,2], dtype='Sparse[int]')\ns.sparse.density","handlingStrategy":"type-guard","validationCode":"from pandas.api.types import is_sparse_dtype\n\ndef is_sparse_series(s) -> bool:\n    return is_sparse_dtype(s.dtype)","typeGuard":"from pandas.api.types import is_sparse_dtype\n\ndef has_sparse_accessor(s) -> bool:\n    return is_sparse_dtype(getattr(s, 'dtype', None))","tryCatchPattern":"try:\n    val = s.sparse.density\nexcept AttributeError as e:\n    if 'sparse accessor' in str(e):\n        val = s.astype('Sparse[float64]').sparse.density\n    else:\n        raise","preventionTips":["Construct sparse Series with dtype='Sparse[...]' from the start.","Guard with pd.api.types.is_sparse_dtype(s.dtype) before .sparse.*.","Watch for .astype() / .values calls that drop the sparse dtype."],"tags":["pandas","sparse","accessor","dtype"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}