{"record":{"id":"17ae9763550654af","repo":"pandas-dev/pandas","slug":"only-integers-slices-and-integer-or-boolean-array","errorCode":null,"errorMessage":"Only integers, slices and integer or boolean arrays are valid indices.","messagePattern":"Only integers, slices and integer or boolean arrays are valid indices\\.","errorType":"exception","errorClass":"IndexError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/arrow/array.py","lineNumber":894,"sourceCode":"            if not len(item):\n                # Removable once we migrate StringDtype[pyarrow] to ArrowDtype[string]\n                if (\n                    isinstance(self._dtype, StringDtype)\n                    and self._dtype.storage == \"pyarrow\"\n                ):\n                    # TODO(infer_string) should this be large_string?\n                    pa_dtype = pa.string()\n                else:\n                    pa_dtype = self._dtype.pyarrow_dtype\n                result = pa.chunked_array([], type=pa_dtype)\n                return self._from_pyarrow_array(result)\n\n            elif item.dtype.kind in \"iu\":\n                return self.take(item)\n            elif item.dtype.kind == \"b\":\n                return self._from_pyarrow_array(self._pa_array.filter(item))\n            else:\n                raise IndexError(\n                    \"Only integers, slices and integer or \"\n                    \"boolean arrays are valid indices.\"\n                )\n        elif isinstance(item, tuple):\n            item = unpack_tuple_and_ellipses(item)\n\n        if item is Ellipsis:\n            # TODO: should be handled by pyarrow?\n            item = slice(None)\n\n        if is_scalar(item) and not is_integer(item):\n            # e.g. \"foo\" or 2.5\n            # exception message copied from numpy\n            raise IndexError(\n                r\"only integers, slices (`:`), ellipsis (`...`), numpy.newaxis \"\n                r\"(`None`) and integer or boolean arrays are valid indices\"\n            )\n        # We are not an array indexer, so maybe e.g. a slice or integer","sourceCodeStart":876,"sourceCodeEnd":912,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/arrow/array.py#L876-L912","documentation":"Raised by ArrowExtensionArray.__getitem__ when the indexer is a numpy array whose dtype kind is neither integer ('i','u') nor boolean ('b'). After check_array_indexer normalizes the input, only integer and boolean masks are valid; float or other-dtype ndarrays hit the final else. This mirrors numpy's indexing contract but gives a pandas-specific message.","triggerScenarios":"Indexing an ArrowExtensionArray/Series with a float numpy array: `s[np.array([1.0, 2.0])]`, `s[np.array([0.5, 1.5])]`, or a boolean-as-int8/uint8 mask whose kind is not 'b'. Also masked indexing where the mask came from arithmetic producing float dtype.","commonSituations":"Boolean masks accidentally upcast to float (e.g. `(s > 0) * 1.0`), computed indices from division yielding floats, JSON/CSV-loaded index arrays defaulting to float64, or passing a pandas Int8/UInt8 column (kind 'i'/'u' fine) vs Float (kind 'f' fails).","solutions":["Cast float indices to intp: s[np.asarray(idx, dtype=np.intp)].","Ensure boolean masks stay bool: s[np.asarray(mask, dtype=bool)].","Use .iloc / .loc and let pandas coerce, or use a list of ints: s[[1,2]].","Recompute the index without float division: use // instead of /."],"exampleFix":"# before\npos = (counts / 2)            # float64 ndarray\nsub = s[pos]                  # IndexError\n# after\npos = (counts // 2).astype(np.intp)\nsub = s[pos]","handlingStrategy":"validation","validationCode":"import numpy as np\n\ndef safe_arrow_index(arr, idx):\n    if isinstance(idx, np.ndarray):\n        if idx.dtype.kind == 'f':\n            idx = idx.astype(np.intp)\n        elif idx.dtype.kind not in ('i', 'u', 'b'):\n            raise IndexError(f'unsupported index dtype {idx.dtype}')\n    return arr[idx]\n\nsub = safe_arrow_index(arrow_arr, positions)","typeGuard":"import numpy as np\n\ndef is_valid_arrow_index_array(idx) -> bool:\n    return isinstance(idx, np.ndarray) and idx.dtype.kind in ('i', 'u', 'b')","tryCatchPattern":"try:\n    sub = arrow_arr[idx]\nexcept IndexError as e:\n    if 'Only integers' in str(e) and hasattr(idx, 'astype'):\n        sub = arrow_arr[np.asarray(idx, dtype=np.intp)]\n    else:\n        raise","preventionTips":["Always cast computed indices to np.intp before indexing extension arrays.","Keep boolean masks as bool dtype (avoid *1.0 upcast).","Validate mask dtype kind is 'b' before filter indexing."],"tags":["pyarrow","indexing","dtype-validation","numpy"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}