Indexación y corte en NumPy: cómo recortar tensores con libertad
1. ¿Por qué la indexación/corte es tan importante?
Al trabajar con deep learning, se manipulan tensores con frecuencia.
- Seleccionar solo los primeros pocos ejemplos de un batch
- Extraer un canal específico (R/G/B) de una imagen
- Cortar solo algunos pasos de tiempo en datos secuenciales
- Obtener solo ciertas clases de las etiquetas
Todas estas tareas se reducen a "indexación e intersección".
Además, la sintaxis de indexación/corte de Tensor en PyTorch es casi idéntica a la de NumPy, por lo que dominarla en NumPy facilita mucho la escritura de código de deep learning.
2. Indexación básica: empezando con 1D
2.1 Indexación de un array 1D
import numpy as np
x = np.array([10, 20, 30, 40, 50])
print(x[0]) # 10
print(x[1]) # 20
print(x[4]) # 50
- Los índices comienzan en 0
x[i]devuelve el elemento i‑ésimo
2.2 Indexación negativa
Para contar desde el final se usan índices negativos.
print(x[-1]) # 50 (último)
print(x[-2]) # 40
PyTorch funciona de la misma manera.
3. Corte básico: start:stop:step
El corte se escribe como 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], desde el principio hasta 3
print(x[2:]) # [30 40 50], desde 2 hasta el final
print(x[:]) # copia completa
Al incluir step se puede establecer un intervalo.
print(x[0:5:2]) # [10 30 50], de 0 a 4 con paso 2
print(x[::2]) # [10 30 50], igual que arriba
En deep learning, por ejemplo, saltar cada dos pasos de tiempo o seleccionar muestras a intervalos regulares resulta muy útil.
4. Indexación en arrays 2D y superiores: filas y columnas
A partir de 2D, estamos esencialmente trabajando con matrices/batches, lo que ya suena a deep learning.
import numpy as np
X = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]) # shape: (3, 3)
4.1 Indexación de fila/columna individual
print(X[0]) # primera fila: [1 2 3]
print(X[1]) # segunda fila: [4 5 6]
print(X[0, 0]) # fila 1, columna 1: 1
print(X[1, 2]) # fila 2, columna 3: 6
X[i]→ fila i‑ésima (array 1D)X[i, j]→ valor en fila i, columna j (escalar)
4.2 Corte de filas
print(X[0:2]) # filas 0 y 1
# [[1 2 3]
# [4 5 6]]
print(X[1:]) # desde la fila 1 hasta el final
# [[4 5 6]
# [7 8 9]]
Este patrón se usa con frecuencia en PyTorch para recortar solo los primeros o últimos ejemplos de un batch.
4.3 Corte de columnas
print(X[:, 0]) # todas las filas, columna 0 → [1 4 7]
print(X[:, 1]) # todas las filas, columna 1 → [2 5 8]
:significa todas las posiciones en esa dimensiónX[:, 0]indica todas las filas, columna 0
En deep learning:
- En un array
(batch_size, feature_dim)se puede extraer una característica específica conX[:, k].
5. 3D y superiores: batch × canal × altura × anchura
Tomemos como ejemplo datos de imagen.
# Supongamos (batch, height, width)
images = np.random.randn(32, 28, 28) # 32 imágenes 28x28
5.1 Extraer una sola muestra
img0 = images[0] # primera imagen, shape: (28, 28)
img_last = images[-1] # última imagen
5.2 Usar solo una parte del batch
first_8 = images[:8] # los primeros 8, shape: (8, 28, 28)
5.3 Cortar una región de la imagen (crop)
# Solo el centro 20x20
crop = images[:, 4:24, 4:24] # shape: (32, 20, 20)
En PyTorch, con un tensor images_torch de forma (32, 1, 28, 28):
center_crop = images_torch[:, :, 4:24, 4:24]
El concepto de indexación/corte es prácticamente idéntico.
6. El corte suele ser una "vista"
Un punto clave:
El resultado de un corte suele ser una vista del array original. Es decir, no se copian datos, sino que se crea una ventana que mira al original.
x = np.array([10, 20, 30, 40, 50])
y = x[1:4] # vista
print(y) # [20 30 40]
y[0] = 999
print(y) # [999 30 40]
print(x) # [ 10 999 30 40 50] ← el original también cambia!
Esta característica:
- Ahorra memoria y es rápida
- Pero puede provocar cambios accidentales en el original
Para crear una copia independiente se usa copy().
x = np.array([10, 20, 30, 40, 50])
y = x[1:4].copy()
y[0] = 999
print(x) # [10 20 30 40 50], el original se mantiene
PyTorch tiene un concepto similar, por lo que comprender la diferencia entre vista y copia facilita la depuración.
7. Indexación booleana: filtrar por condición
La indexación booleana se usa para seleccionar solo los elementos que cumplen una condición.
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 > 0produce un array deTrue/Falsex[mask]devuelve solo los índices donde la máscara esTrue
Ejemplo combinado:
X = np.array([[1, 2, 3],
[4, 5, 6],
[-1, -2, -3]])
pos = X[X > 0]
print(pos) # [1 2 3 4 5 6]
En deep learning, patrones comunes incluyen:
- Extraer solo muestras que cumplan una condición (por ejemplo, etiquetas específicas)
- Calcular la pérdida solo sobre valores que cumplan una máscara
PyTorch funciona de manera casi idéntica:
import torch
x = torch.tensor([1, -2, 3, 0, -5, 6])
mask = x > 0
pos = x[mask]
8. Indexación con arrays/lists de enteros (Fancy Indexing)
Se pueden usar arrays o listas de enteros para extraer múltiples posiciones a la vez.
x = np.array([10, 20, 30, 40, 50])
idx = [0, 2, 4]
print(x[idx]) # [10 30 50]
En 2D también funciona.
X = np.array([[1, 2],
[3, 4],
[5, 6]]) # shape: (3, 2)
rows = [0, 2]
print(X[rows])
# [[1 2]
# [5 6]]
En deep learning, por ejemplo:
- Seleccionar muestras aleatorias de un batch con un array de índices mezclados
- Agrupar solo ciertas posiciones de etiquetas/predicciones para estadísticas
PyTorch también admite este estilo.
9. Patrones de indexación comunes
Desde la perspectiva de deep learning, los patrones habituales son:
import numpy as np
# (batch, feature)
X = np.random.randn(32, 10)
# 1) Los primeros 8 ejemplos
X_head = X[:8] # (8, 10)
# 2) Una característica específica (ej. columna 3)
f3 = X[:, 3] # (32,)
# 3) Solo índices pares
X_even = X[::2] # (16, 10)
# 4) Muestras con etiqueta 1
labels = np.random.randint(0, 3, size=(32,))
mask = labels == 1
X_cls1 = X[mask] # solo muestras con etiqueta 1
# 5) Mezclar aleatoriamente y dividir en 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]
Estos patrones se aplican casi igual en tensores de PyTorch. En resumen, dominar la indexación de NumPy equivale a poder manipular tensores de manera libre y eficiente.
10. Conclusión
Para recapitular:
- Indexación:
x[i],x[i, j], índices negativos - Corte:
start:stop:step,:, indexación multidimensional (X[:, 0],X[:8],X[:, 4:8]) - El corte suele ser una vista, por lo que el original puede cambiar → usar
copy()si se necesita una copia - Indexación booleana: filtrar por condición (
x[x > 0],X[labels == 1]) - Indexación con arrays de enteros: seleccionar múltiples posiciones a la vez (
x[[0,2,4]])
Con estos conceptos, podrás trabajar con tensores de PyTorch para recortar batches, seleccionar canales, aplicar máscaras y mezclar muestras de forma mucho más fluida.

No hay comentarios.