Modifying Arrays via Indexing
Change values in place by assigning to an index, slice, mask or index list — and why changing a slice changes the original.
Data is rarely perfect. A scorer typed Rohit's runs wrong, rain-hit matches must be set to 0, or every score above 100 needs to be capped. Every selection you learned in this chapter can also appear on the left side of = to change the array in place.
Definition
Modifying through indexing (index assignment) means writing
arr[selection] = value, whereselectionis any index, slice, boolean mask or index list. NumPy writesvalueinto exactly those positions of the original array, in place.valuecan be a single scalar (copied to every selected position) or an array whose shape matches (or broadcasts to) the selection.
- In place — no new array is created; the existing
arrchanges. - Scalar value —
arr[mask] = 0sets every selected element to 0. - Array value — must have the same number of elements in a compatible shape, e.g.
arr[0:3] = [1, 2, 3]. - dtype is kept — assigning
45.9into anint64array stores45(the decimal part is truncated, not rounded).
Syntax
python
arr[i] = v # one element
arr[r, c] = v # one cell of a 2D array
arr[a:b] = v # a range (scalar or matching array)
arr[:, c] = v # a whole column
arr[mask] = v # every element where mask is True
arr[[i, j, k]] = v # specific positions (fancy)
arr += 5 # in-place arithmetic on the whole array| Selection on the left | Affects | Value on the right |
|---|---|---|
integer / [r, c] | one element | one scalar |
| slice | a range / rectangle | scalar, or array of the slice's shape |
| boolean mask | all True positions | scalar, or 1D array with one value per True |
| index list | listed positions | scalar, or one value per index |
Example — fix single values and ranges
python
import numpy as np
scores = np.array([
[72, 45, 88, 31, 64, 0, 103, 52], # row 0: Virat
[56, 0, 74, 88, 32, 45, 61, 17], # row 1: Rohit
[45, 32, 0, 67, 18, 54, 78, 22], # row 2: Hardik
])
scores[1, 1] = 12 # Rohit's match 2 was wrongly entered as 0
scores[2, 5:] = [60, 80, 30] # Hardik's last 3 matches corrected
scores[:, 0] = 0 # match 1 was abandoned -> 0 for everyone
print(scores)text
[[ 0 45 88 31 64 0 103 52]
[ 0 12 74 88 32 45 61 17]
[ 0 32 0 67 18 60 80 30]]How it works: each line selects a region and overwrites it in the original array. The column assignment scores[:, 0] = 0 uses a scalar, which is copied into every selected cell.
Example — conditional updates with a mask and an index list
python
virat_runs = np.array([72, 45, 88, 31, 64, 0, 103, 52, 19, 77, 41, 93, 28, 66])
runs = virat_runs.copy() # work on a copy so virat_runs stays intact
runs[runs > 90] = 90 # cap every score above 90
print("Capped :", runs)
runs[[0, 1]] = [100, 100] # matches 1 and 2 overwritten
print("Edited :", runs)
runs[runs == 0] += 1 # add 1 to ducks only
print("No ducks:", runs)
print("Original:", virat_runs)text
Capped : [72 45 88 31 64 0 90 52 19 77 41 90 28 66]
Edited : [100 100 88 31 64 0 90 52 19 77 41 90 28 66]
No ducks: [100 100 88 31 64 1 90 52 19 77 41 90 28 66]
Original: [ 72 45 88 31 64 0 103 52 19 77 41 93 28 66]How it works: runs[mask] = 90 writes 90 wherever the mask is True. runs[mask] += 1 reads the selected values, adds 1 and writes them back. Because we started from .copy(), virat_runs is untouched.
Example — the type is kept (truncation)
python
virat_runs = np.array([72, 45, 88, 31, 64, 0, 103, 52, 19, 77, 41, 93, 28, 66])
runs = virat_runs.copy()
runs[0] = 45.9
print(runs[:3], runs.dtype)text
[45 45 88] int64How it works: the array's dtype is int64, so NumPy converts 45.9 to an integer by dropping the decimal part. Convert first with runs.astype(float) if you need decimals.
⚠️ Warning — slices are views
A basic slice does not copy the data; it is a view — a new window onto the same memory. So modifying a slice modifies the original array too:
python
virat_runs = np.array([72, 45, 88, 31, 64, 0, 103, 52, 19, 77, 41, 93, 28, 66])
first5 = virat_runs[:5] # a VIEW, not a copy
first5[0] = 999
print("first5 :", first5)
print("virat_runs:", virat_runs) # changed too!
safe = virat_runs[5:10].copy() # an independent COPY
safe[:] = 0
print("safe :", safe)
print("virat_runs:", virat_runs) # unchanged by the copytext
first5 : [999 45 88 31 64]
virat_runs: [999 45 88 31 64 0 103 52 19 77 41 93 28 66]
safe : [0 0 0 0 0]
virat_runs: [999 45 88 31 64 0 103 52 19 77 41 93 28 66]| Selection | View or copy? | Does editing the result change the original? |
|---|---|---|
index / slice a[2:5], a[:, 0] | view | yes |
boolean mask a[a > 50] | copy | no |
fancy a[[0, 2]] | copy | no |
a[2:5].copy() | copy | no |
Note: "Editing the result" is different from "assigning through a selection".
a[a > 50] = 0always changesa(that's assignment). Butb = a[a > 50]; b[0] = 0does not (b is a copy). Views vs copies,np.shares_memoryand.baseare covered in detail in the Copy vs View chapter.
Common mistakes
- ❌ Taking a slice "to experiment" and accidentally corrupting the original data. ✅
part = arr[a:b].copy(). - ❌
arr[0:3] = [1, 2]→ValueError: could not broadcast input array from shape (2,) into shape (3,). ✅ Give 3 values or a scalar. - ❌ Expecting
int_arr[0] = 4.7to store 4.7. ✅ It stores 4 — convert with.astype(float)first. - ❌
b = a[a > 50]; b[:] = 0expectingato change. ✅ Writea[a > 50] = 0directly.
Interview tip
Q: You do b = a[1:4]; b[0] = 100. Does a change? What about b = a[[1, 2, 3]]?
A: With the slice, yes — basic slicing returns a view sharing a's memory, so a[1] becomes 100. With the index list (fancy indexing), no — it returns a copy.
Key points to remember
- Any selection can be assigned to: arr[i] = v, arr[a:b] = v, arr[mask] = v, arr[[i, j]] = v.
- Assignment changes the original array in place; no new array is created.
- A scalar on the right is written to every selected position; an array must match (or broadcast to) the selection's shape.
- arr[mask] += 1 updates only the elements where the mask is True.
- The array's dtype is kept: assigning 45.9 into an int array stores 45 (truncated).
- Basic slices are VIEWS: editing a slice edits the original. Use .copy() for an independent array.
- Boolean and fancy indexing results are copies — editing them does not affect the original.
Try it yourself
Correct and update scores in place
Slice = view, .copy() = independent
Practice: rain-affected matches
Revision Flashcards
Tap a card to flip it and see the answer.
