pandas-dev/pandas · error · IndexError
only integers, slices (`:`), ellipsis (`...`), numpy.newaxis
Error message
only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices
What it means
Raised in SparseArray.__getitem__ when the key is not an integer, not a tuple, not a slice, and not list-like (e.g. a string label or a float). SparseArray is positional-only, so label or non-integer-scalar indexing is invalid. The message is mirrored from numpy for familiarity.
Source
Thrown at pandas/core/arrays/sparse/array.py:1093
# should be shifted. NB: here we are careful to also not shift by a
# negative value for a case like [0, 1][-100:] where the start index
# should be treated like 0
if start > 0:
sp_index -= start
# Length of our result should match applying this slice to a range
# of the length of our original array
new_len = len(range(len(self))[key])
new_sp_index = make_sparse_index(new_len, sp_index, self.kind)
return type(self)._simple_new(sp_vals, new_sp_index, self.dtype)
else:
indices = np.arange(len(self), dtype=np.int32)[key]
return self.take(indices)
elif not is_list_like(key):
# e.g. "foo" or 2.5
# exception message copied from numpy
raise IndexError(
r"only integers, slices (`:`), ellipsis (`...`), numpy.newaxis "
r"(`None`) and integer or boolean arrays are valid indices"
)
else:
if isinstance(key, SparseArray):
# NOTE: If we guarantee that SparseDType(bool)
# has only fill_value - true, false or nan
# (see GH PR 44955)
# we can apply mask very fast:
if is_bool_dtype(key):
if isna(key.fill_value):
return self.take(key.sp_index.indices[key.sp_values])
if not key.fill_value:
return self.take(key.sp_index.indices)
n = len(self)
mask = np.full(n, True, dtype=np.bool_)
mask[key.sp_index.indices] = FalseView on GitHub (pinned to 71959b8cb9)
Solutions
- Use integer positions: sparse_arr[int(i)].
- For label access, index the Series: pd.Series(sparse_arr, index=labels)['foo'].
- Coerce computed indices to int and validate they are in range.
Example fix
// before val = sparse_arr['2020-01-01'] // after val = pd.Series(sparse_arr, index=date_index)['2020-01-01']
Defensive patterns
Strategy: type-guard
Validate before calling
import pandas as pd
from pandas.api.types import is_integer, is_list_like
def getitem_sparse_safe(arr, key, labels=None):
if isinstance(key, str) or (not is_integer(key) and not is_list_like(key) and not isinstance(key, slice)):
if labels is None:
raise IndexError('positional SparseArray; cannot use label key')
return pd.Series(arr, index=labels)[key]
return arr[int(key) if is_integer(key) else key] Type guard
def is_positional_key(key) -> bool:
from pandas.api.types import is_integer
import numpy as np
return is_integer(key) or isinstance(key, (slice, np.ndarray, list)) Try / catch
try:
return arr[key]
except IndexError as e:
if 'valid indices' in str(e):
return pd.Series(arr, index=labels)[key]
raise Prevention
- Use integer positions for SparseArray indexing.
- Do label lookups through the wrapping Series.
- Coerce float indices to int before indexing.
When it happens
Trigger: sparse_arr['foo']; sparse_arr[2.5]; passing a column label or datetime to index a SparseArray directly instead of going through the Series label index.
Common situations: Treating a SparseArray like a Series (.loc semantics); float indices from computations that should be int; label-based lookups forwarded to .array.
Related errors
- Cannot slice with Ellipsis
- Cannot construct {type(self).__name__} from scalar data. Pas
- 'data' must have a single column, not '{ncol}'
- Unable to avoid copy while creating an array as requested.
- Cannot modify read-only array
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/5f706a65bbba6fa7.
Report an issue: GitHub.