Por qué NumPy existe
Valeria ya tiene las ventas de su café de las últimas semanas en una lista de Python. Bruno, su primo caótico, le dice: "Para sumarle el IVA a cada venta, haz un for". Pixel, el robot sarcástico, suspira: "Claro, y para cortar el pan usa un hacha."
NumPy (Numerical Python) te da un objeto llamado array: una tabla de números del mismo tipo guardada de forma compacta. Lo mejor es que opera sobre todos los elementos a la vez, sin escribir bucles. A eso se le llama vectorización, y es entre 10 y 100 veces más rápido que un for.
import numpy as np
ventas = np.array([120, 95, 130, 80, 150])
print(ventas * 1.16) # IVA a todas a la vez
Crear arrays
Hay muchas formas de crearlos:
np.array([1, 2, 3]) # desde una lista
np.zeros(4) # [0. 0. 0. 0.]
np.ones(3) # [1. 1. 1.]
np.arange(0, 10, 2) # [0 2 4 6 8]
np.linspace(0, 1, 5) # 5 puntos entre 0 y 1
Cada array tiene atributos útiles: .shape (la forma), .dtype (el tipo de dato) y .ndim (número de dimensiones).
Matrices: arrays de 2 dimensiones
Si pasas una lista de listas, obtienes una matriz. Piensa en una tabla: filas y columnas.
tabla = np.array([[10, 20, 30],
[40, 50, 60]])
print(tabla.shape) # (2, 3) -> 2 filas, 3 columnas
print(tabla[1, 2]) # 60 (fila 1, columna 2)
print(tabla[:, 0]) # [10 40] toda la columna 0
Puedes cambiar la forma con .reshape(): np.arange(6).reshape(2, 3) crea la misma matriz de 2×3.
Operaciones sin bucles
Las operaciones aritméticas actúan elemento a elemento:
a = np.array([1, 2, 3])
b = np.array([10, 20, 30])
print(a + b) # [11 22 33]
print(a * b) # [10 40 90]
print(a ** 2) # [1 4 9]
Y también hay funciones de resumen: .sum(), .max(), .min(), .argmax() (la posición del máximo).
Máscaras booleanas: filtrar con condiciones
Una comparación devuelve un array de True y False. Si lo usas como índice, te quedas solo con los elementos que cumplen:
ventas = np.array([120, 95, 130, 80, 150])
buenas = ventas[ventas > 100]
print(buenas) # [120 130 150]
Broadcasting: cuando las formas no coinciden
NumPy "estira" automáticamente el valor más pequeño. Por eso ventas * 1.16 funciona: el número 1.16 se aplica a cada elemento. También puedes sumar un vector a cada fila de una matriz si las columnas coinciden.
| Operación | Resultado |
|---|---|
x + 1 | suma 1 a todo |
x > 5 | array de booleanos |
x[x > 5] | solo los mayores que 5 |
x.sum() | suma total |
Errores típicos
- Mezclar lista y array:
[1, 2] * 2repite la lista ([1, 2, 1, 2]), peronp.array([1, 2]) * 2multiplica ([2 4]). - Usar
anden vez de&: para combinar máscaras usa(x > 1) & (x < 5), con paréntesis. - Olvidar que el slicing no incluye el final:
x[0:3]da 3 elementos. - Dimensiones incompatibles: sumar arrays de forma (3,) y (4,) lanza un error.
💡 Truco: si dudas de la forma de un array, imprime x.shape antes de hacer cualquier cosa.
Historia: el bucle de Bruno
Bruno entregó un programa que calculaba el IVA de 1 millón de ventas con un for. Tardó tanto que Valeria se tomó dos cafés. Pixel lo reescribió con ventas * 1.16 y terminó antes de que se enfriara el primero. "Menos bucles, más café", sentenció el robot.
Reto
Crea un array con las ventas de cinco días, súbele 10% a todas y quédate solo con las que superen 100. ¿Cuántas quedaron? Pista: una máscara y .sum() de booleanos te lo cuentan.