pandas-dev/pandas · error · IndexError
only integers, slices (`:`), ellipsis (`...`)…
Error message
only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices
What it means
IndexError (message copied verbatim from numpy) raised by SparseArray.__getitem__ when the key is neither an integer, slice, tuple, nor list-like. Typical offenders are string keys ('foo') or float scalars (2.5).
Solutions
- Use integer positional indices: arr[int(x)].
- For label access, go through pd.Series(arr, index=labels)[label].
- Coerce float keys with int() when they represent valid positions.
Example fix
// before arr[2.0] # raises // after arr[int(2.0)]
Defensive patterns
Strategy: validation
Validate before calling
def coerce_index_key(key):
if isinstance(key, float) and key.is_integer():
return int(key)
return key Type guard
def is_invalid_scalar_key(key) -> bool:
import numbers
return not isinstance(key, (int, numbers.Integral, slice, tuple, list)) Try / catch
try:
arr[key]
except IndexError as e:
if "valid indices" in str(e):
key = int(key)
out = arr[key]
else:
raise Prevention
- Use integer positional indices for SparseArray.
- Use Series for label-based access.
- Coerce float positions to int.
When it happens
Trigger: arr['foo'], arr[2.5], or any scalar key whose type is not recognized as integer or list-like.
Common situations: Confusing positional SparseArray indexing with label-based Series indexing; passing a float index value that should have been an int.
Related errors
- Cannot slice with Ellipsis
- Cannot slice with
- index is out of bounds: must be an integer between
- Only integers, slices and integer or boolean arrays are…
- only integers, slices (`:`), ellipsis (`...`)…
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/5f706a65bbba6fa7.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/arrays/sparse/array.py:1098
# 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 3b7651241d)