Skip to main content
v2026.11,986 entries · CC-BY 4.0

Index of NumPy: Indexing and Slicing Arrays

How to index a NumPy array by position, slice, integer array or boolean mask, with view-versus-copy rules and the traps that change results silently.

Written and maintained by CASRAI Editorial Board

Published · Last updated

On this page

Researchers and analysts searching “index of NumPy” usually want to know how to pull values out of a NumPy array: by position, by slice, by a list of positions, or by a true/false mask. This guide covers all four, says which return a view and which return a copy, and flags the traps in the official NumPy documentation that most often change research results silently.

Short answer: NumPy indexes arrays with square brackets. Integers and slices (x[1:7:2]) are “basic” indexing and return views; integer arrays and boolean arrays are “advanced” indexing and return copies. Positions start at 0 and negative numbers count from the end. (Source: NumPy user guide, “Indexing on ndarrays”, read 2026-11-08.)

What indexing is used for in research

Analysis code constantly selects part of an array: the readings from one condition, the rows that survived a quality filter, or every non-missing value before computing a mean. NumPy’s indexing syntax does this without loops. This page concerns array indexing; it is not about the index() method of Python lists or tuples.

Numpy indexing, indexing in NumPy, NumPy index, index NumPy

These phrasings all refer to the same mechanism. The NumPy documentation names three kinds: basic indexing (integers and slices), advanced indexing (integer or boolean arrays), and field access for structured arrays.

Install or access

Install from the official NumPy installation page (numpy.org/install). With pip, create and activate a virtual environment, then install:

python -m venv my-env
source my-env/bin/activate      # macOS/Linux
my-env\Scripts\activate         # Windows
pip install numpy

With conda: conda create -n my-env, then conda activate my-env, then conda install numpy (defaults or conda-forge channel). Check the install with import numpy as np; print(np.__version__). If importing fails with a C-extension error, NumPy maintains a troubleshooting page at numpy.org/doc/stable/user/troubleshooting-importerror.html.

Step-by-step: selecting values from an array

1. Basic indexing and slicing

Use start:stop:step. The stop position is excluded.

import numpy as np
x = np.arange(10)
x[1:7:2]     # array([1, 3, 5])
x[-2]        # 8
x[-3:3:-1]   # array([7, 6, 5, 4])

An ellipsis (...) stands for as many full slices as needed, and np.newaxis (an alias of None) adds an axis of length one. The documentation states: “All arrays generated by basic slicing are always views of the original array.” Changing a slice therefore changes the original array.

2. Indexing with an array of positions (advanced)

x = np.arange(10, 1, -1)
x[np.array([3, 3, -3, 8])]   # array([7, 7, 4, 2])

y = np.arange(35).reshape(5, 7)
y[np.array([0, 2, 4]), np.array([0, 1, 2])]   # array([ 0, 15, 30])

With one index array per axis, NumPy pairs them element by element (here the positions (0,0), (2,1) and (4,2)). Positions may repeat. The documentation states: “Advanced indexing always returns a copy of the data (contrast with basic slicing that returns a view).”

3. Selecting a block of rows and columns with np.ix_

x = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])
rows = [0, 3]
columns = [0, 2]
x[np.ix_(rows, columns)]
# array([[ 0,  2],
#        [ 9, 11]])
x[rows, columns]           # array([ 0, 11])

The same two lists give different results. x[rows, columns] pairs them and returns two values; np.ix_ builds the cross-product and returns the 2×2 block. The documentation calls this “the most important thing to remember about indexing with multiple advanced indices.”

4. Boolean masks: filtering by a condition

x = np.array([1., np.nan, 3.])
x[~np.isnan(x)]            # array([1., 3.])

x = np.array([1., -1., -2., 3])
x[x < 0] += 20             # x is now array([ 1., 19., 18.,  3.])

This is the standard way to drop missing readings before computing a statistic: the mask ~np.isnan(x) is true where a value is present. A boolean mask on a multi-dimensional array returns a one-dimensional result in row-major order. The documentation notes that a boolean index obj behaves like x[obj.nonzero()]. For finding positions with a condition rather than values, see NumPy where.

5. Mixing slices and index arrays

y[np.array([0, 2, 4]), 1:3] equals y[:, 1:3][np.array([0, 2, 4]), :]: the slice is applied to one axis and the index array to the other. When advanced indices are separated by a slice or np.newaxis, their dimensions go first in the result; when adjacent, they stay in place. For an array x of shape (10, 20, 30, 40, 50), the documentation’s example x[:, ind_1, :, ind_2] yields shape (2, 3, 4, 10, 30, 50).

6. numpy.take

numpy.take(a, indices, axis=None, out=None, mode='raise') picks elements along one axis; with axis=None the array is flattened first. np.take([4, 3, 5, 7, 6, 8], [0, 1, 4]) returns array([4, 3, 6]). The mode argument sets out-of-range behaviour: 'raise' (error), 'wrap', or 'clip' (which disables negative indexing). np.take(arr, indices, axis=3) is equivalent to arr[:, :, :, indices, ...].

Output and how to read it: view or copy, and out-of-range behaviour

Method Selects by Result Out-of-range position
Basic indexing / slices Integers, start:stop:step View of the original IndexError for a single integer
Integer-array indexing Array of positions Copy IndexError
Boolean mask True/false array Copy (1-D result) Selects by condition, not position
numpy.take Positions along one axis New array Set by mode: raise, wrap or clip

Source: NumPy user guide, “Indexing on ndarrays”, and the numpy.take reference page, both read 2026-11-08. The view/copy distinction matters for research code: assigning into a slice edits your source data, while assigning into the result of advanced indexing does not. The documentation also advises an explicit copy() when a small slice would otherwise keep a large array alive in memory. x[...] always returns a view.

Three traps that change results without an error

  • Paired versus cross-product indices. x[rows, columns] and x[np.ix_(rows, columns)] return different things (step 3).
  • Repeated indices and in-place addition. x[np.array([1, 1, 3, 1])] += 1 increments x[1] only once, not three times, per the documentation.
  • Silent truncation on assignment. Assigning a float into an integer array truncates it (x[1] = 1.2 stores 1). Assigning a complex number raises TypeError (can’t convert complex to int). Check the dtype before writing computed values back.

Troubleshooting

  • IndexError: index 3 is out of bounds for axis 0 with size 3 means a position exceeds the axis length. Valid positions run from -size to size-1.
  • IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (3,) (2,) means the index arrays have incompatible lengths. Make them equal length, or use np.ix_ if you want a cross-product.
  • Unexpected changes to original data after editing a “subset” usually mean the subset was a view. Call .copy() first.
  • Related array operations: NumPy delete, ravel in NumPy, NumPy arrays and reversing a vector in NumPy. If you are coming from MATLAB, see MATLAB indexing for the matching concepts on that side.

FAQ

What does “index of NumPy” mean?

It normally means how to index a NumPy array: select elements by position, slice, integer array or boolean mask using square brackets. It is distinct from the list.index() method in core Python.

Do NumPy arrays start at 0 or 1?

0. x[0] is the first element and x[-1] the last. The examples above, such as x[-2] returning 8 on np.arange(10), follow this.

Does indexing return a view or a copy?

Basic slicing returns a view; advanced indexing (integer or boolean arrays) returns a copy, per the NumPy user guide.

How do I remove NaN values from an array?

x[~np.isnan(x)] keeps only the values that are not NaN.

Sources

  • NumPy user guide, “Indexing on ndarrays”: numpy.org/doc/stable/user/basics.indexing.html (read 2026-11-08).
  • NumPy reference, numpy.take: numpy.org/doc/stable/reference/generated/numpy.take.html (read 2026-11-08).
  • NumPy installation instructions: numpy.org/install (read 2026-11-08).

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about Index of NumPy: Indexing and Slicing Arrays

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →