NumPy-indexering & slicing: hoe je tensors moeiteloos kunt knippen
1. Waarom is indexering/slicing zo belangrijk?
Bij deep learning kom je vaak met tensors te maken.
- Alleen de eerste paar samples uit een batch halen
- Alleen een specifiek kanaal (R/G/B) uit een afbeelding selecteren
- Alleen een deel van de tijdstappen uit sequentiedata knippen
- Alleen een bepaalde klasse uit labels extraheren
Al deze handelingen komen uiteindelijk neer op "indexering (indexing) & slicing".
En de indexering/slicing-syntaxis van PyTorch’s Tensor is bijna identiek aan die van NumPy, dus als je NumPy goed onder de knie hebt, wordt het schrijven van deep‑learning‑code veel eenvoudiger.
2. Basisindexering: 1‑dimensies
2.1 Indexering van een 1‑D array
import numpy as np
x = np.array([10, 20, 30, 40, 50])
print(x[0]) # 10
print(x[1]) # 20
print(x[4]) # 50
- Indexen beginnen bij 0
x[i]geeft het i‑de element
2.2 Negatieve indexen
Als je vanaf het einde wilt tellen, gebruik je negatieve indexen.
print(x[-1]) # 50 (laatste)
print(x[-2]) # 40
PyTorch werkt hier ook op dezelfde manier.
3. Basis slicing: start:stop:step
Slicing wordt gebruikt als x[start:stop:step].
x = np.array([10, 20, 30, 40, 50])
print(x[1:4]) # [20 30 40], 1 ≤ i < 4
print(x[:3]) # [10 20 30], vanaf 0 tot 3 (exclusief)
print(x[2:]) # [30 40 50], vanaf 2 tot het einde
print(x[:]) # kopie van het geheel
Met een step kun je een interval instellen.
print(x[0:5:2]) # [10 30 50], 0 tot 4 met stap 2
print(x[::2]) # [10 30 50], hetzelfde
In deep learning is dit handig om bijvoorbeeld elke tweede tijdstap te overslaan of om een bepaalde interval van samples te kiezen.
4. Indexering van 2‑D en hoger: rijen en kolommen
Een 2‑D array is in feite een matrix/batch, dus het begint al de deep‑learning‑sfeer te krijgen.
import numpy as np
X = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]) # vorm: (3, 3)
4.1 Enkelvoudige indexering van rijen/kolommen
print(X[0]) # eerste rij: [1 2 3]
print(X[1]) # tweede rij: [4 5 6]
print(X[0, 0]) # rij 1, kolom 1: 1
print(X[1, 2]) # rij 2, kolom 3: 6
X[i]→ i‑de rij (1‑D array)X[i, j]→ waarde op rij i, kolom j (scalar)
4.2 Rij‑slicing
print(X[0:2]) # rijen 0 en 1
# [[1 2 3]
# [4 5 6]]
print(X[1:]) # vanaf rij 1 tot het einde
# [[4 5 6]
# [7 8 9]]
Dit is een patroon dat je vaak ziet bij het knippen van een deel van een batch in PyTorch.
4.3 Kolom‑slicing
print(X[:, 0]) # alle rijen, kolom 0 → [1 4 7]
print(X[:, 1]) # alle rijen, kolom 1 → [2 5 8]
:betekent "hele dimensie"X[:, 0]betekent "alle rijen, kolom 0"
In deep learning:
- Bij een array van vorm
(batch_size, feature_dim)kun je een specifieke feature selecteren metX[:, k].
5. 3‑D en hoger: batch × kanaal × hoogte × breedte
Laten we een voorbeeld nemen met beelddata.
# (batch, hoogte, breedte) aannemen
images = np.random.randn(32, 28, 28) # 32 beelden, 28x28
5.1 Een enkel beeld selecteren
img0 = images[0] # eerste beeld, vorm: (28, 28)
img_last = images[-1] # laatste beeld
5.2 Een deel van de batch gebruiken
first_8 = images[:8] # eerste 8, vorm: (8, 28, 28)
5.3 Een deel van het beeld knippen (crop)
# midden 20x20 gebied
crop = images[:, 4:24, 4:24] # vorm: (32, 20, 20)
In PyTorch ziet het er zo uit:
# images_torch: (32, 1, 28, 28) een tensor
center_crop = images_torch[:, :, 4:24, 4:24]
Het concept van indexering/slicing blijft vrijwel hetzelfde.
6. Slicing is meestal een "view"
Een belangrijk punt:
Het resultaat van slicing is meestal een view van de originele array. Dat betekent dat er geen nieuwe data gekopieerd wordt, maar dat je een venster op de originele data hebt.
x = np.array([10, 20, 30, 40, 50])
y = x[1:4] # view
print(y) # [20 30 40]
y[0] = 999
print(y) # [999 30 40]
print(x) # [ 10 999 30 40 50] ← originele array verandert!
Deze eigenschap heeft voordelen:
- Bespaart geheugen en is sneller
- Maar kan leiden tot onverwachte wijzigingen van de originele data
Wil je een volledig aparte array, gebruik dan copy().
x = np.array([10, 20, 30, 40, 50])
y = x[1:4].copy()
y[0] = 999
print(x) # [10 20 30 40 50], origineel ongewijzigd
PyTorch heeft een vergelijkbaar concept, dus het is handig om het verschil "view vs copy" te kennen voor debugging.
7. Booleaanse indexering: filteren op voorwaarden
Booleaanse indexering wordt gebruikt om alleen de elementen te selecteren die een bepaalde voorwaarde voldoen.
import numpy as np
x = np.array([1, -2, 3, 0, -5, 6])
mask = x > 0
print(mask) # [ True False True False False True]
pos = x[mask]
print(pos) # [1 3 6]
x > 0→ array vanTrue/Falsex[mask]→ alleen deTrue‑posities
Voorbeeld van combinaties:
X = np.array([[1, 2, 3],
[4, 5, 6],
[-1, -2, -3]])
pos = X[X > 0]
print(pos) # [1 2 3 4 5 6]
In deep learning wordt dit vaak gebruikt om:
- Alleen samples met een bepaalde label te extraheren
- Bij verliesberekening een masker toe te passen en alleen bepaalde waarden te middelen
PyTorch werkt hier ook op dezelfde manier:
import torch
x = torch.tensor([1, -2, 3, 0, -5, 6])
mask = x > 0
pos = x[mask]
8. Indexering met een integer array / lijst (Fancy Indexing)
Met een array of lijst van integer‑indexen kun je meerdere posities in één keer selecteren.
x = np.array([10, 20, 30, 40, 50])
idx = [0, 2, 4]
print(x[idx]) # [10 30 50]
Ook in 2‑D werkt het.
X = np.array([[1, 2],
[3, 4],
[5, 6]]) # vorm: (3, 2)
rows = [0, 2]
print(X[rows])
# [[1 2]
# [5 6]]
In deep learning kun je bijvoorbeeld:
- Een willekeurig gemengde indexarray gebruiken om een batch te trekken
- Alleen bepaalde labels/predictions verzamelen voor statistieken
PyTorch ondersteunt dezelfde stijl.
9. Veelgebruikte indexeringspatronen samengevat
Hier zijn enkele patronen die vaak voorkomen in deep learning:
import numpy as np
# (batch, feature)
X = np.random.randn(32, 10)
# 1) Alleen de eerste 8 samples
X_head = X[:8] # (8, 10)
# 2) Alleen een specifieke feature (bijv. kolom 3)
f3 = X[:, 3] # (32,)
# 3) Alleen even‑index samples
X_even = X[::2] # (16, 10)
# 4) Alleen samples met label 1
labels = np.random.randint(0, 3, size=(32,))
mask = labels == 1
X_cls1 = X[mask] # samples met label 1
# 5) Random shuffle en splitsen in train/val
indices = np.random.permutation(len(X))
train_idx = indices[:24]
val_idx = indices[24:]
X_train = X[train_idx]
X_val = X[val_idx]
Deze patronen werken vrijwel identiek op PyTorch‑tensors. Het beheersen van NumPy‑indexering is dus gelijk aan het kunnen "knippen, mengen en selecteren" van tensor‑data.
10. Afsluiting
Samengevat:
- Indexering:
x[i],x[i, j], negatieve indexen - Slicing:
start:stop:step,:, multi‑dimensies (X[:, 0],X[:8],X[:, 4:8]) - Slicing levert meestal een view; gebruik
copy()als je een aparte array wilt - Booleaanse indexering: filteren met voorwaarden (
x[x > 0],X[labels == 1]) - Integer‑array indexering: selecteren met een lijst van indices (
x[[0,2,4]])
Met deze kennis kun je PyTorch‑tensors moeiteloos manipuleren: batch‑slicing, kanaalselectie, masker‑toepassing, en sample‑mixing.

댓글이 없습니다.