pandas-dev/pandas · error · IndexError

Only integers, slices and integer or boolean arrays are…

Error message

Only integers, slices and integer or boolean arrays are valid indices.

What it means

Raised by ArrowExtensionArray.__getitem__ when the indexer is a numpy array whose dtype kind is neither integer ('i'/'u') nor boolean ('b'). The __getitem__ override dispatches integer arrays to self.take and boolean arrays to pa.ChunkedArray.filter; any other ndarray kind (float, object, string, datetime) is invalid as a positional indexer.

Solutions

  1. Cast the indexer to intp before indexing: arr[idx.astype(np.intp)].
  2. If the floats are coordinates, round and cast explicitly: arr[np.round(idx).astype(np.intp)].
  3. Use a boolean mask instead of integer positions when possible.
  4. If you intended label-based indexing, use a Series/Index accessor rather than the raw extension array __getitem__.

Example fix

# before
import numpy as np
arr = pd.array([10, 20, 30], dtype="int64[pyarrow]")
idx = np.array([0.0, 2.0])
arr[idx]  # raises IndexError

# after
arr[idx.astype(np.intp)]
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np

def coerce_indexer(idx):
    arr = np.asarray(idx)
    if arr.dtype.kind == 'f':
        if not np.all(arr == arr.astype(np.int64)):
            raise ValueError('non-integer float indexer')
        return arr.astype(np.intp)
    if arr.dtype.kind == 'b':
        return arr
    if arr.dtype.kind in 'iu':
        return arr.astype(np.intp)
    raise TypeError(f'unsupported indexer dtype {arr.dtype}')

Type guard

import numpy as np

def is_valid_positional_indexer(idx: np.ndarray) -> bool:
    return idx.ndim == 1 and idx.dtype.kind in 'iub'

Prevention

When it happens

Trigger: Indexing arr[np_float_array] where the indexer is a float ndarray (e.g. np.array([0.0, 1.0])); indexing with an ndarray of Python objects or strings; using the result of a computation that returned float indices without casting to intp.

Common situations: Computed indexers from division or math that yield float arrays; numpy boolean masks accidentally upcast to int8/int16 then to non-integer; passing a pandas Series of floats as a positional indexer; mixing positional and label-based indexing.

Related errors


AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11). Data as JSON: /api/errors/17ae9763550654af. Report an issue: GitHub.

Appendix: source

Thrown at pandas/core/arrays/arrow/array.py:919

            if not len(item):
                # Removable once we migrate StringDtype[pyarrow] to ArrowDtype[string]
                if (
                    isinstance(self._dtype, StringDtype)
                    and self._dtype.storage == "pyarrow"
                ):
                    # TODO(infer_string) should this be large_string?
                    pa_dtype = pa.string()
                else:
                    pa_dtype = self._dtype.pyarrow_dtype
                result = pa.chunked_array([], type=pa_dtype)
                return self._from_pyarrow_array(result)

            elif item.dtype.kind in "iu":
                return self.take(item)
            elif item.dtype.kind == "b":
                return self._from_pyarrow_array(self._pa_array.filter(item))
            else:
                raise IndexError(
                    "Only integers, slices and integer or "
                    "boolean arrays are valid indices."
                )
        elif isinstance(item, tuple):
            item = unpack_tuple_and_ellipses(item)

        if item is Ellipsis:
            # TODO: should be handled by pyarrow?
            item = slice(None)

        if is_scalar(item) and not is_integer(item):
            # 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"
            )
        # We are not an array indexer, so maybe e.g. a slice or integer

View on GitHub (pinned to 3b7651241d)