Indexación y Remodelación de NumPy
La indexación selecciona y reorganiza datos de ndarray a lo largo de ejes; la remodelación cambia la forma sin cambiar los valores cuando el tamaño total se mantiene constante.
Receta
Tarjeta de referencia rápida - lista para copiar y pegar.
import numpy as np
matrix = np.arange(12).reshape(3, 4)
rows = matrix[1:3, ::2] # selecciona filas 1-2, cada otra columna
cols = matrix[:, [0, 3]] # indexación avanzada de columnas 0 y 3
flat = matrix.reshape(-1) # vista 1-D cuando es posibleCuándo usar esto:
- Extracción de submatrices para procesamiento por lotes
- Reordenamiento de dimensiones antes de pasar datos a modelos de ML
- Creación de máscaras para actualizaciones condicionales
- Alineación de formas para broadcasting a través de ejes
Ejemplo de Trabajo
import numpy as np
# 4 regiones x 6 meses
sales = np.array(
[[10, 12, 11, 13, 14, 15],
[8, 9, 10, 9, 11, 12],
[20, 18, 19, 21, 22, 23],
[5, 6, 5, 7, 6, 8]],
dtype=np.int32,
)
# Solo Q1: meses 0-2, todas las regiones
q1 = sales[:, 0:3]
# Dos regiones principales por ventas totales
totals = sales.sum(axis=1)
top_idx = np.argsort(totals)[-2:]
top_regions = sales[top_idx]
# Apilar vectores de región como columnas para correlación
wide = sales.T # forma (6, 4) - meses como filas
# Marcar meses donde cualquier región superó 20
hot_months = np.where(sales.max(axis=0) >= 20)[0]
print("q1 shape:", q1.shape)
print("top regions:", top_idx)
print("hot months:", hot_months)Lo que esto demuestra:
- Slicing de columnas con
inicio:finenaxis=1 - Reducción a lo largo de
axis=1y luegoargsortpara selección de filas .T(transpuesta) como atajo de remodelaciónnp.whereenmax(axis=0)para indexar columnas por condición
Profundización
Cómo Funciona
- El slicing básico (
inicio:fin:paso) usa strides para producir una vista que comparte memoria. - La indexación con arrays de enteros recopila elementos en orden arbitrario y generalmente copia.
- Las máscaras booleanas deben coincidir con la forma broadcastable;
arr[mask]devuelve una selección 1-D. reshapedevuelve una vista cuando los strides lo permiten; de lo contrario, copia.
Modos de Indexación
| Estilo | Ejemplo | ¿Copia? |
|---|---|---|
| Slice | a[2:5] | Generalmente vista |
| Lista de enteros | a[[1, 3]] | Copia |
| Máscara booleana | a[a > 0] | Copia |
np.take | np.take(a, idx, axis=0) | Configurable |
Convenciones de Ejes
axis | Significado en 2-D |
|---|---|
0 | Hacia abajo por las filas (agrega columnas) |
1 | A través de las columnas (agrega filas) |
-1 | Última dimensión |
Notas de Python
import numpy as np
# Insertar eje para broadcasting
row = np.array([1, 2, 3])
col = row[:, np.newaxis] # forma (3, 1)
# ravel vs flatten: flatten siempre copia
a = np.arange(6).reshape(2, 3)
flat_view = a.ravel()
flat_copy = a.flatten()Errores Comunes
- Asignación a través de indexación avanzada -
a[[0, 1]] = 5puede no comportarse como la asignación repetida de slices. Solución: asignar a.copy()o usarnp.put. - Vistas con strides negativos - invertir con
a[::-1]puede hacer que algunas remodelaciones copien inesperadamente. Solución: llamar a.copy()antes de extensiones C posteriores. - Forma de la máscara booleana -
a[mask]en 2-D necesita una forma de máscara(filas, columnas)o broadcastable. Solución:mask = mask & (a > 0)con formas alineadas. - Slices con diferencia de uno -
a[1:3]excluye el índice 3; a diferencia derange. Solución: recordar que el final es exclusivo. - Desajuste de tamaño en reshape -
reshape(3, 5)en 12 elementos lanza un error. Solución: usar-1para una dimensión inferida:reshape(3, -1).
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
np.einsum | Contracciones explícitas de tensores | Selecciones simples de filas/columnas |
pandas .loc | Filas/columnas etiquetadas | Kernels ndarray puramente numéricos |
np.take_along_axis | Ordenar valores por fila | Suficientes slices de matriz completa |
np.moveaxis | Reordenar tensores 3-D+ | .T simple en 2-D |
Preguntas Frecuentes
¿Cuál es la diferencia entre vista y copia?
- Las vistas comparten el buffer de datos; las copias son independientes.
- Modificar una vista afecta a la original a menos que hayas copiado primero.
¿Cómo selecciono cada otra fila?
import numpy as np
a = np.arange(10)
every_other = a[::2]¿Cómo intercambio filas y columnas?
matrix.Tonp.transpose(matrix)para 2-D.np.swapaxes(a, 0, 1)cuando el rango es > 2.
¿Puede reshape cambiar el número total de elementos?
- No, el tamaño total debe coincidir:
np.prod(shape) == a.size. - Usa
np.resizesolo cuando quieras intencionalmente repetición o truncamiento.
¿Cómo indexo un volumen 3-D?
vol[z, y, x]- el eje más lento primero en orden C.- Documenta el significado del eje en las docstrings de las funciones.
¿Por qué la indexación plana difiere de la 2-D?
a[5]en 2-D usa el índice ravel en orden C.- Prefiere
a[row, col]onp.unravel_indexpara mayor claridad.
¿Cómo filtro y mantengo la forma 2-D?
- Máscara booleana en filas:
a[mask, :]mantiene las columnas intactas. a[mask]solo aplana los elementos seleccionados a 1-D.
¿Qué hace el elipsis `...`?
a[..., 0]selecciona el índice 0 en el último eje, todos los ejes anteriores completos.- Útil para arrays N-D sin listar cada dos puntos.
¿Cómo apilar vs concatenar?
np.stackañade un nuevo eje;np.concatenateune a lo largo de un eje existente.np.vstack/hstackson envoltorios de conveniencia.
¿Es x[i, j} lo mismo que x[(i, j)]?
- Sí para ndarray - el índice de tupla lista las dimensiones.
x[i][j]indexa dos veces y puede fallar en estructuras no cuadradas.
Relacionado
- NumPy Arrays - creación, dtypes, broadcasting
- pandas Series & DataFrames - análogos de
.loc/.iloc - Rendimiento y Memoria - vistas vs copias a escala
- Conceptos Básicos de Análisis de Datos - ejemplos introductorios
Versiones de Stack: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.