NumPy: Arrays y Operaciones Vectorizadas
El Motor Matematico de Data ScienceNumPy (Numerical Python) es la libreria fundamental para computacion numerica en Python. Es el motor que hace funcionar a Pandas, Scikit-learn, TensorFlow y practicamente toda libreria de data science. Entender NumPy te da una base solida para todo lo que viene despues.
Por que NumPy y no listas de Python?
La respuesta corta: velocidad. NumPy opera sobre arrays homogeneos en memoria contigua, lo que permite operaciones vectorizadas que son 10-100x mas rapidas que los bucles de Python.
import numpy as np
import time
# Comparacion de velocidad
tamanio = 1_000_000
# Con lista de Python
lista = list(range(tamanio))
inicio = time.time()
resultado_lista = [x ** 2 for x in lista]
tiempo_lista = time.time() - inicio
# Con NumPy
array = np.arange(tamanio)
inicio = time.time()
resultado_numpy = array ** 2
tiempo_numpy = time.time() - inicio
print(f"Lista Python: {tiempo_lista:.4f}s")
print(f"NumPy: {tiempo_numpy:.4f}s")
print(f"NumPy es {tiempo_lista/tiempo_numpy:.0f}x mas rapido")
Creando Arrays
import numpy as np
# Desde una lista
ventas = np.array([120, 135, 98, 145, 167, 189])
print(ventas) # [120 135 98 145 167 189]
print(type(ventas)) # <class 'numpy.ndarray'>
print(ventas.dtype) # int64
# Array de floats
temperaturas = np.array([22.5, 25.3, 18.7, 30.1, 27.8])
print(temperaturas.dtype) # float64
# Arrays especiales
ceros = np.zeros(10) # [0. 0. 0. ...]
unos = np.ones(5) # [1. 1. 1. 1. 1.]
rango = np.arange(0, 100, 10) # [ 0 10 20 30 40 50 60 70 80 90]
lineal = np.linspace(0, 1, 5) # [0. 0.25 0.5 0.75 1. ]
# Array 2D (matriz)
matriz = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(matriz.shape) # (3, 3)
print(matriz.ndim) # 2
Arrays aleatorios (para simulaciones)
np.random.seed(42) # Para reproducibilidad
# Distribucion normal con parametros de negocio
# Simular salarios: media $75,000, desviacion $15,000
salarios_simulados = np.random.normal(loc=75000, scale=15000, size=500)
print(f"Media: ${salarios_simulados.mean():,.0f}")
print(f"Desv. Est.: ${salarios_simulados.std():,.0f}")
# Enteros aleatorios
dados = np.random.randint(1, 7, size=10000) # 10,000 tiradas de dado
print(f"Promedio dado: {dados.mean():.3f}") # Deberia ser ~3.5
# Muestra aleatoria de un array
poblacion = np.arange(1, 1001)
muestra = np.random.choice(poblacion, size=50, replace=False)
print(f"Muestra de {len(muestra)} personas")
Operaciones Vectorizadas
La magia de NumPy esta en que las operaciones se aplican a todo el array sin necesidad de bucles.
ventas_q1 = np.array([45000, 52000, 38000, 61000, 55000])
ventas_q2 = np.array([48000, 49000, 42000, 58000, 63000])
# Operaciones elemento a elemento
diferencia = ventas_q2 - ventas_q1
crecimiento = (ventas_q2 - ventas_q1) / ventas_q1 * 100
total = ventas_q1 + ventas_q2
print(f"Diferencia: {diferencia}")
print(f"Crecimiento %: {crecimiento.round(1)}")
print(f"Total semestral: {total}")
# Comparaciones (retornan arrays booleanos)
ventas_altas = ventas_q1 > 50000
print(ventas_altas) # [False True False True True]
# Contar cuantos cumplieron el objetivo
print(f"Vendedores sobre $50k: {ventas_altas.sum()} de {len(ventas_q1)}")
print(f"Porcentaje: {ventas_altas.mean():.0%}")
Funciones Estadisticas
np.random.seed(42)
datos = np.random.normal(loc=50000, scale=12000, size=200)
print(f"Media: {datos.mean():,.2f}")
print(f"Mediana: {np.median(datos):,.2f}")
print(f"Desv. Estandar: {datos.std():,.2f}")
print(f"Varianza: {datos.var():,.2f}")
print(f"Minimo: {datos.min():,.2f}")
print(f"Maximo: {datos.max():,.2f}")
# Percentiles
print(f"Percentil 25: {np.percentile(datos, 25):,.2f}")
print(f"Percentil 50: {np.percentile(datos, 50):,.2f}")
print(f"Percentil 75: {np.percentile(datos, 75):,.2f}")
# Suma acumulada
ventas_diarias = np.random.randint(100, 500, size=30)
ventas_acumuladas = np.cumsum(ventas_diarias)
print(f"Ventas acumuladas del mes: {ventas_acumuladas[-1]:,}")
Indexacion y Slicing
ventas = np.array([120, 135, 98, 145, 167, 189, 201, 178, 156, 190, 210, 245])
meses = np.array(["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"])
# Indexacion booleana (SUPER importante en data science)
mascara = ventas > 170
print(f"Meses con ventas > 170: {meses[mascara]}")
print(f"Valores: {ventas[mascara]}")
# Multiples condiciones
mascara_rango = (ventas >= 150) & (ventas <= 200)
print(f"Ventas entre 150-200: {ventas[mascara_rango]}")
# np.where: condicionales vectorizados
clasificacion = np.where(ventas >= 150, "Alta", "Baja")
print(clasificacion)
Operaciones con Matrices (2D)
ventas_regiones = np.array([
[150, 160, 170, 180], # Norte
[120, 130, 125, 140], # Sur
[200, 210, 195, 220], # Este
[90, 95, 100, 110] # Oeste
])
regiones = ["Norte", "Sur", "Este", "Oeste"]
trimestres = ["Q1", "Q2", "Q3", "Q4"]
# Total por region
for i, region in enumerate(regiones):
print(f" {region}: {ventas_regiones[i].sum():,}")
# Total por trimestre
for j, trimestre in enumerate(trimestres):
print(f" {trimestre}: {ventas_regiones[:, j].sum():,}")
print(f"Total general: {ventas_regiones.sum():,}")
Video Recomendado
Curso de NumPy Completo en Espanol
Ejercicio Practico
Crea un notebook 04_numpy.ipynb y resolve:
- Genera un array con 1000 salarios aleatorios (distribucion normal, media $60,000, desviacion $15,000)
- Calcula todas las estadisticas descriptivas
- Usa indexacion booleana para encontrar salarios por encima del percentil 90
- Crea una matriz 4x3 con datos de ventas y calcula totales por producto y por mes
- Simula 10,000 tiradas de dos dados y calcula la distribucion de las sumas
💡 Concepto Clave
Revisemos los puntos más importantes de esta lección antes de continuar.
Resumen
- NumPy arrays son 10-100x mas rapidos que listas de Python
- Operaciones vectorizadas: se aplican a todo el array sin bucles
- Indexacion booleana: filtrar datos con condiciones
- np.where: condicionales vectorizados
- Funciones estadisticas: mean, median, std, percentile
- Generacion aleatoria: random.normal, random.randint para simulaciones
🧠 Pon a prueba tu conocimiento
¿Cuál es el aspecto más importante que aprendiste en esta lección?
- Comprendo el concepto principal y puedo explicarlo con mis palabras
- Entiendo cómo aplicarlo en mi situación específica
- Necesito repasar algunas partes antes de continuar
- Quiero ver más ejemplos prácticos del tema
✅ ¡Excelente! Continúa con la siguiente lección para profundizar más.