pandas-dev/pandas · error · AttributeError

Can only use the '.sparse' accessor with Sparse data.

Error message

Can only use the '.sparse' accessor with Sparse data.

What it means

Raised by SparseAccessor._validate when the `.sparse` accessor is used on a Series whose dtype is not a SparseDtype. Accessors are registered only for sparse-backed Series, so accessing `.sparse` on a regular dense Series is a programming error rather than a missing attribute.

Source

Thrown at pandas/core/arrays/sparse/accessor.py:78

    See Also
    --------
    Series.sparse.to_coo : Create a scipy.sparse.coo_matrix from a Series with
        MultiIndex.
    Series.sparse.from_coo : Create a Series with sparse values from a
        scipy.sparse.coo_matrix.

    Examples
    --------
    >>> ser = pd.Series([0, 0, 2, 2, 2], dtype="Sparse[int]")
    >>> ser.sparse.density
    0.6
    >>> ser.sparse.sp_values
    array([2, 2, 2])
    """

    def _validate(self, data) -> None:
        if not isinstance(data.dtype, SparseDtype):
            raise AttributeError(self._validation_msg)

    def _delegate_property_get(self, name: str, *args, **kwargs):
        return getattr(self._parent.array, name)

    def _delegate_method(self, name: str, *args, **kwargs):
        if name == "from_coo":
            return self.from_coo(*args, **kwargs)
        elif name == "to_coo":
            return self.to_coo(*args, **kwargs)
        else:
            raise ValueError

    @classmethod
    def from_coo(cls, A, dense_index: bool = False) -> Series:
        """
        Create a Series with sparse values from a scipy.sparse.coo_matrix.

        This method takes a ``scipy.sparse.coo_matrix`` (coordinate format) as input and

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Construct with an explicit sparse dtype: pd.Series([...], dtype='Sparse[int]').
  2. Convert an existing dense Series: s.astype('Sparse[int]').
  3. Check before accessing: if isinstance(s.dtype, pd.SparseDtype): ... else: use the dense path.

Example fix

// before
density = pd.Series([0,0,1,2]).sparse.density
// after
density = pd.Series([0,0,1,2], dtype='Sparse[int]').sparse.density
Defensive patterns

Strategy: type-guard

Validate before calling

import pandas as pd

def sparse_density(s):
    if not isinstance(s.dtype, pd.SparseDtype):
        s = s.astype('Sparse[int]')
    return s.sparse.density

Type guard

def is_sparse_series(s) -> bool:
    import pandas as pd
    return isinstance(s.dtype, pd.SparseDtype)

Try / catch

try:
    return s.sparse.density
except AttributeError as e:
    if 'sparse accessor' in str(e):
        return s.astype('Sparse[int]').sparse.density
    raise

Prevention

When it happens

Trigger: pd.Series([1,2,3]).sparse.density; pd.Series([0,0,1]).astype('int64').sparse; a Series that was sparse but got densified by an operation (e.g. .astype('float64')).

Common situations: Forgetting dtype='Sparse[int]' when constructing the Series; an intermediate op (groupby/merge/astype) silently converting SparseArray to a dense ndarray; loading data without specifying sparse dtype.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/9ac0ec49ddb907fe. Report an issue: GitHub.