Met indexatie en slicing selecteer je elementen of deelgebieden van een array. Boolean indexing laat je elementen filteren op basis van een conditie โ dit is รฉรฉn van de krachtigste en meest gebruikte technieken in NumPy รฉn Pandas.
โ ๏ธ We behandelen ook het cruciale verschil tussen een view en een copy โ een bron van subtiele bugs.
import numpy as npIndexatie in 1Dยถ
a = np.array([10, 20, 30, 40, 50])
print(a[0]) # first element: 10
print(a[-1]) # last element: 50
print(a[-2]) # second to last: 4010
50
40
Slicing in 1Dยถ
Syntax: array[start:stop:step] โ stop is exclusief.
a = np.arange(10) # [0 1 2 3 4 5 6 7 8 9]
print(a[2:5]) # [2 3 4]
print(a[:4]) # [0 1 2 3]
print(a[6:]) # [6 7 8 9]
print(a[::2]) # every other element: [0 2 4 6 8]
print(a[::-1]) # reversed: [9 8 7 6 5 4 3 2 1 0][2 3 4]
[0 1 2 3]
[6 7 8 9]
[0 2 4 6 8]
[9 8 7 6 5 4 3 2 1 0]
Indexatie en slicing in 2Dยถ
In 2D gebruik je kommaโs: array[row, column].
M = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
print(M[0, 0]) # 1 โ first row, first column
print(M[2, -1]) # 12 โ last row, last column
print(M[1, :]) # [5 6 7 8] โ entire second row
print(M[:, 2]) # [3 7 11] โ entire third column1
12
[5 6 7 8]
[ 3 7 11]
# Sub-matrix: rows 0-1, columns 1-2
print(M[0:2, 1:3])[[2 3]
[6 7]]
โ ๏ธ View vs. copyยถ
Dit is รฉรฉn van de meest voorkomende bronnen van verborgen bugs in NumPy.
Een slice geeft een view terug โ een venster op de originele data. Aanpassen van de view wijzigt de originele array!
Gebruik .copy() wanneer je een onafhankelijke kopie wilt.
original = np.array([1, 2, 3, 4, 5])
# View โ NOT a copy
view = original[1:4]
view[0] = 99 # also modifies original!
print("original:", original) # [1 99 3 4 5] โ changed!original: [ 1 99 3 4 5]
original = np.array([1, 2, 3, 4, 5])
# Copy โ independent
copy_arr = original[1:4].copy()
copy_arr[0] = 99
print("original: ", original) # [1 2 3 4 5] โ unchanged
print("copy_arr: ", copy_arr) # [99 3 4]original: [1 2 3 4 5]
copy_arr: [99 3 4]
# Check whether an array is a view
original = np.arange(5)
view = original[::2]
print("is view:", view.base is original) # True
copy_arr = original.copy()
print("is view:", copy_arr.base is original) # Falseis view: True
is view: False
Boolean indexingยถ
Met boolean indexing filteer je elementen van een array via een masker van True/False-waarden. Dit is de basis van data-filtering in NumPy en Pandas.
scores = np.array([45, 82, 67, 91, 53, 78, 88, 39])
# Step 1: create a boolean mask
mask = scores >= 70
print("mask:", mask) # [False True False True ...]mask: [False True False True False True True False]
# Step 2: apply the mask
high_scores = scores[mask]
print("high scores:", high_scores)high scores: [82 91 78 88]
# Inline shorthand โ mask directly inside the brackets
print(scores[scores >= 70])[82 91 78 88]
# Combine conditions with & (AND) and | (OR)
# Note: use & and | (not 'and'/'or'), and wrap conditions in parentheses!
print(scores[(scores >= 60) & (scores < 90)]) # between 60 and 90
print(scores[(scores < 50) | (scores > 85)]) # below 50 OR above 85[82 67 78 88]
[45 91 88 39]
# Replace elements via boolean mask
data = np.array([1, -2, 3, -4, 5, -6])
data[data < 0] = 0 # set negative values to zero
print(data) # [1 0 3 0 5 0][1 0 3 0 5 0]
NaN-waarden detecteren en behandelenยถ
NaN (Not a Number) is de standaard manier om ontbrekende waarden voor te stellen in NumPy.
readings = np.array([1.5, np.nan, 3.2, np.nan, 4.8, 2.1])
# Detect NaN values
nan_mask = np.isnan(readings)
print("NaN mask:", nan_mask)
print("Number of NaNs:", np.sum(nan_mask))
# Filter: keep only valid values
valid = readings[~nan_mask] # ~ inverts the mask
print("Valid values:", valid)
print("Mean:", np.mean(valid))NaN mask: [False True False True False False]
Number of NaNs: 2
Valid values: [1.5 3.2 4.8 2.1]
Mean: 2.9
Fancy indexingยถ
Met fancy indexing selecteer je elementen via een lijst van indices. In tegenstelling tot slicing geeft dit altijd een copy.
names = np.array(["Alice", "Bob", "Charlie", "Diana", "Eve"])
# Select specific indices
print(names[[0, 2, 4]]) # ['Alice' 'Charlie' 'Eve']
# Combined with np.argsort โ sort by another array
scores = np.array([88, 74, 95, 82, 91])
order = np.argsort(scores)[::-1] # indices from high to low
print(names[order]) # names sorted by score['Alice' 'Charlie' 'Eve']
['Charlie' 'Eve' 'Alice' 'Diana' 'Bob']
Oefeningenยถ
Oefening 1 โ Gegeven:
M = np.arange(1, 26).reshape(5, 5)Selecteer (zonder de array te wijzigen):
De derde rij (index 2)
De laatste kolom
De submatrix bestaande uit rijen 1โ3 en kolommen 2โ4
M = np.arange(1, 26).reshape(5, 5)
print(M)
# your solution here[[ 1 2 3 4 5]
[ 6 7 8 9 10]
[11 12 13 14 15]
[16 17 18 19 20]
[21 22 23 24 25]]
Oefening 2 โ Demonstreer het view-vs-copy-probleem:
Maak een array
original = np.array([10, 20, 30, 40, 50])Maak een slice
part = original[1:4]en paspart[0] = 99toeDruk
originalaf โ wat zie je?Herhaal met
.copy()en vergelijk
# your solution hereOefening 3 โ Gegeven temperatures = np.array([22.1, -5.3, 18.4, 0.0, -12.7, 30.1, 15.6, -0.5]):
Selecteer alle temperaturen boven 15ยฐC
Selecteer alle temperaturen tussen -10ยฐC en 10ยฐC
Tel het aantal temperaturen beneden 0ยฐC
temperatures = np.array([22.1, -5.3, 18.4, 0.0, -12.7, 30.1, 15.6, -0.5])
# your solution hereOefening 4 โ Gegeven data = np.array([3.1, np.nan, 7.4, np.nan, 2.8, np.nan, 9.1, 4.5]):
Tel het aantal NaN-waarden
Bereken het gemiddelde van de geldige waarden (zonder de NaNโs)
Vervang de NaNโs door het gemiddelde van de geldige waarden (maak eerst een copy!)
data = np.array([3.1, np.nan, 7.4, np.nan, 2.8, np.nan, 9.1, 4.5])
# your solution hereOefening 5 โ Gegeven twee arrays:
names = np.array(["Alice", "Bob", "Charlie", "Diana", "Eve"])
scores = np.array([88, 74, 95, 82, 91])Selecteer de namen van studenten met een score > 85, gesorteerd van hoog naar laag.
names = np.array(["Alice", "Bob", "Charlie", "Diana", "Eve"])
scores = np.array([88, 74, 95, 82, 91])
# your solution here