Skip to content

2. Indexing & slicing

Beginner · 8 min read

2.1 1-D arrays — like lists

import numpy as np

a = np.array([10, 20, 30, 40, 50])
print(a[0], a[-1])        # first, last
print(a[1:4])             # stop is excluded
print(a[::2])             # every second value
print(a[::-1])            # reversed
Output
10 50
[20 30 40]
[10 30 50]
[50 40 30 20 10]

2.2 2-D arrays — [row, column]

m = np.arange(12).reshape(3, 4)
print(m)
print(m[1, 2])        # row 1, column 2
print(m[0])           # whole first row
print(m[:, 1])        # whole second column
print(m[:2, 1:3])     # rows 0-1, columns 1-2
Output
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
6
[0 1 2 3]
[1 5 9]
[[1 2]
 [5 6]]

2.3 Boolean masks — filter by a condition

A comparison gives an array of True/False; use it to pick values.

scores = np.array([0.91, 0.42, 0.77, 0.15, 0.66])
mask = scores > 0.5
print(mask)
print(scores[mask])                          # only the matching values
print(scores[(scores > 0.4) & (scores < 0.8)])   # & = and, | = or, ~ = not
print(mask.sum(), "scores above 0.5")         # True counts as 1
Output
[ True False  True False  True]
[0.91 0.77 0.66]
[0.42 0.77 0.66]
3 scores above 0.5

Use & and |, not and / or

and / or work on single values. For arrays use &, |, ~ — and wrap each condition in brackets, because & binds more tightly than >.

2.4 Fancy indexing — pick by position list

docs = np.array(["faq", "policy", "blog", "pricing", "terms"])
best = [3, 0, 2]                 # e.g. indices of the top-3 matches
print(docs[best])
print(scores[best])
Output
['pricing' 'faq' 'blog']
[0.15 0.91 0.77]

2.5 np.where — if/else on a whole array

labels = np.where(scores >= 0.5, "relevant", "skip")
print(labels)
print(np.where(scores >= 0.5)[0])      # indices where the condition holds
print(np.clip(scores, 0.2, 0.8))       # limit values to a range
Output
['relevant' 'skip' 'relevant' 'skip' 'relevant']
[0 2 4]
[0.8  0.42 0.77 0.2  0.66]

2.6 Views vs copies — a common trap

Slicing returns a view: it shares memory with the original, so changing it changes the original.

original = np.arange(5)
view = original[1:4]
view[0] = 99                     # changes `original` too!
print(original)

safe = original[1:4].copy()      # an independent copy
safe[0] = -1
print(original)                  # unchanged this time
print(np.shares_memory(original, view), np.shares_memory(original, safe))
Output
[ 0 99  2  3  4]
[ 0 99  2  3  4]
True False

Note

Boolean masks and fancy indexing (a[[0, 2]]) always return copies; plain slices (a[1:4]) return views. Call .copy() whenever you plan to modify a slice on its own.

Practice

  • From np.arange(20), select the even numbers greater than 7 with one mask.
  • Given a 5 × 3 array, select rows 0, 2 and 4 with fancy indexing.

Next: Maths & broadcasting →