pandas-dev/pandas · error · IndexError
cannot do a non-empty take from an empty axes.
Error message
cannot do a non-empty take from an empty axes.
What it means
IndexError from SparseArray._take_with_fill when the array is empty (len==0) but the caller requested a non-empty take that is not entirely the -1 fill sentinel. Empty source arrays can only honor an all-fill take.
Source
Thrown at pandas/core/arrays/sparse/array.py:1191
if indices.min() < -1:
raise ValueError(
"Invalid value in 'indices'. Must be between -1 "
"and the length of the array."
)
if indices.max() >= len(self):
raise IndexError("out of bounds value in 'indices'.")
if len(self) == 0:
# Empty... Allow taking only if all empty
if (indices == -1).all():
dtype = np.result_type(self.sp_values, type(fill_value))
taken = np.empty_like(indices, dtype=dtype)
taken.fill(fill_value)
return taken
else:
raise IndexError("cannot do a non-empty take from an empty axes.")
# sp_indexer may be -1 for two reasons
# 1.) we took for an index of -1 (new)
# 2.) we took a value that was self.fill_value (old)
sp_indexer = self.sp_index.lookup_array(indices)
new_fill_indices = indices == -1
old_fill_indices = (sp_indexer == -1) & ~new_fill_indices
if self.sp_index.npoints == 0 and old_fill_indices.all():
# We've looked up all valid points on an all-sparse array.
taken = np.full(
sp_indexer.shape, fill_value=self.fill_value, dtype=self.dtype.subtype
)
elif self.sp_index.npoints == 0:
# Use the old fill_value unless we took for an index of -1
_dtype = np.result_type(self.dtype.subtype, type(fill_value))
if self.dtype.subtype.kind == "b" and _dtype.kind != "b":View on GitHub (pinned to 3b7651241d)
Solutions
- Guard the empty case: if len(arr) == 0: return empty result.
- Only take with all -1 sentinels when allow_fill=True on an empty array.
- Use pd.Series(arr).reindex(...).fillna(...) which handles empties.
Example fix
// before pd.arrays.SparseArray([]).take([0], allow_fill=True) # raises // after empty = pd.arrays.SparseArray([]) out = empty.take([-1, -1], allow_fill=True) # all-fill is allowed
Defensive patterns
Strategy: validation
Validate before calling
def safe_take_empty(arr, indices, fill_value=None):
if len(arr) == 0:
import numpy as np
if np.all(np.asarray(indices) == -1):
return arr.take(indices, allow_fill=True, fill_value=fill_value)
return arr # empty result
return arr.take(indices, allow_fill=True, fill_value=fill_value) Type guard
def empty_source(arr) -> bool:
return len(arr) == 0 Try / catch
try:
arr.take(indices, allow_fill=True)
except IndexError as e:
if 'empty axes' in str(e):
out = arr # nothing to take
else:
raise Prevention
- Short-circuit take calls on empty arrays.
- Only request all -1 sentinels for fill takes on empties.
- Use Series.reindex for robustness on empty groups.
When it happens
Trigger: pd.arrays.SparseArray([]).take([0], allow_fill=True); any take on an empty sparse Series where indices contains a real position.
Common situations: Branches that forgot to short-circuit on empty input; groupby/reindex paths that produce empty groups but still call take.
Related errors
- Invalid value in 'indices'. Must be between -1 and the lengt
- out of bounds value in 'indices'.
- 'indices' must be an array, not a scalar '{indices}'.
- pd.api.extensions.take requires a numpy.ndarray, ExtensionAr
- cannot do a non-empty take
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/6ba4541ec50e7968.
Report an issue: GitHub.