NumPy (Numerical Python) es la biblioteca fundamental para la computación científica en Python. Desarrollada originalmente por Travis Oliphant en 2005, se ha convertido en la columna vertebral de prácticamente todo el ecosistema moderno de ciencia de datos de Python.
Si trabajas con análisis de datos, machine learning, ingeniería o cualquier área que requiera cálculos numéricos eficientes, NumPy es indispensable. En esta guía completa, dominarás desde los conceptos básicos hasta técnicas avanzadas de manipulación de arrays.
📦 ¿Qué es NumPy y Por Qué Usarlo?
NumPy es una biblioteca que proporciona soporte para arrays multidimensionales de alto rendimiento, junto con funciones matemáticas de alto nivel para trabajar con esos arrays. La principal ventaja de NumPy sobre las listas tradicionales de Python es la velocidad: las operaciones con arrays NumPy son decenas a cientos de veces más rápidas que las equivalentes con listas nativas.
Esta eficiencia ocurre porque NumPy utiliza memoria continua e implementa operaciones vectorizadas que aprovechan la estructura de datos para realizar cálculos en paralelo. Además, NumPy es la base de otras bibliotecas esenciales como Pandas, Matplotlib, Scikit-learn y TensorFlow.
🚀 Instalación y Configuración
Instalación vía pip
# Instalación estándar
pip install numpy
# Verificar versión
import numpy as np
print(np.__version__)
Instalación vía conda
# Para usuarios de Anaconda/Miniconda
conda install numpy
🔧 Arrays NumPy: El Corazón de la Biblioteca
Creando Arrays Básicos
import numpy as np
# Array a partir de una lista
arr1 = np.array([1, 2, 3, 4, 5])
print(arr1)
# Array de ceros
zeros = np.zeros(5)
print(zeros)
# Array de unos
unos = np.ones((3, 3)) # matriz 3x3
print(unos)
# Array con valores aleatorios
aleatorios = np.random.rand(5)
print(aleatorios)
# Array con secuencia
secuencia = np.arange(0, 10, 2) # de 0 a 10, paso 2
print(secuencia)
# Array con espacio lineal
espaciado = np.linspace(0, 1, 5) # 5 valores entre 0 y 1
print(espaciado)
Propiedades de los Arrays
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(f"Dimensiones: {arr.ndim}") # 2
print(f"Forma: {arr.shape}") # (2, 3)
print(f"Total elementos: {arr.size}") # 6
print(f"Tipo de datos: {arr.dtype}") # int64
print(f"Memoria (bytes): {arr.itemsize * arr.size}")
📊 Operaciones Matemáticas con NumPy
Operaciones Aritméticas
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
# Operaciones básicas - aplicadas elemento a elemento
print(arr + 10) # [11, 12, 13, 14, 15]
print(arr - 5) # [-4, -3, -2, -1, 0]
print(arr * 2) # [2, 4, 6, 8, 10]
print(arr / 2) # [0.5, 1.0, 1.5, 2.0, 2.5]
print(arr ** 2) # [1, 4, 9, 16, 25]
# Operaciones entre arrays
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print(a + b) # [5, 7, 9]
print(a * b) # [4, 10, 18]
Funciones Matemáticas
import numpy as np
arr = np.array([0, np.pi/2, np.pi, 3*np.pi/2])
# Funciones trigonométricas
print(np.sin(arr)) # [0. 1. 0. -1.]
print(np.cos(arr)) # [1. 0. -1. 0.]
print(np.tan(arr)) # [0. inf 0. inf]
# Otras funciones importantes
arr2 = np.array([1, 4, 9, 16])
print(np.sqrt(arr2)) # [1. 2. 3. 4.]
print(np.log(arr2)) # [0. 1. 2. 2.77...]
print(np.abs([-1, -2, 3])) # [1, 2, 3]
# Estadísticas
notas = np.array([7.5, 8.0, 6.5, 9.0, 7.0])
print(f"Media: {np.mean(notas):.2f}") # 7.6
print(f"Mediana: {np.median(notas):.2f}") # 7.5
print(f"Desviación estándar: {np.std(notas):.2f}") # 0.98
print(f"Varianza: {np.var(notas):.2f}") # 0.96
print(f"Máximo: {np.max(notas)}") # 9.0
print(f"Mínimo: {np.min(notas)}") # 6.5
🎯 Indexación y Slicing
Acceso a Elementos
import numpy as np
arr = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
# Acceso por índice
print(arr[0, 0]) # 1
print(arr[1, 2]) # 7
print(arr[-1, -1]) # 12
# Indexación negativa
print(arr[-1]) # [9, 10, 11, 12]
print(arr[-1, -2]) # 11
Slicing (Rebanado)
import numpy as np
arr = np.arange(1, 21).reshape(4, 5)
# Filas y columnas específicas
print(arr[0, :]) # primera fila
print(arr[:, 2]) # tercera columna
# Intervalos
print(arr[1:3, 1:4]) # filas 1-2, columnas 1-3
# Con paso
print(arr[::2]) # todas las filas, paso 2
print(arr[::2, ::2]) # filas y columnas con paso 2
# Máscara booleana
arr2 = np.array([10, 20, 30, 40, 50])
mascara = arr2 > 25
print(arr2[mascara]) # [30, 40, 50]
# Indexación fancy
indices = [0, 2, 4]
print(arr2[indices]) # [10, 30, 50]
🔄 Manipulación de Arrays
reshape() y flatten()
import numpy as np
arr = np.arange(1, 13)
print(arr.shape) # (12,)
# Redimensionar a matriz 3x4
matriz = arr.reshape(3, 4)
print(matriz)
# [[1 2 3 4]
# [5 6 7 8]
# [9 10 11 12]]
# flatten() - aplanar a 1D
print(matriz.flatten())
# ravel() - similar a flatten pero devuelve vista
print(matriz.ravel())
transpose() y swapaxes()
import numpy as np
matriz = np.array([[1, 2, 3],
[4, 5, 6]])
print(matriz.T)
# [[1 4]
# [2 5]
# [3 6]]
# swapaxes() - intercambiar ejes
arr3d = np.arange(1, 13).reshape(2, 3, 2)
print(arr3d.swapaxes(1, 2).shape) # (2, 2, 3)
Concatenación y Split
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# Concatenar
print(np.concatenate([a, b])) # [1 2 3 4 5 6]
print(np.hstack([a, b])) # horizontal stack
print(np.vstack([a, b])) # vertical stack
# Split
arr = np.array([1, 2, 3, 4, 5, 6])
print(np.split(arr, 3)) # [array([1,2]), array([3,4]), array([5,6])]
💡 Broadcasting
El broadcasting es una técnica poderosa de NumPy que permite realizar operaciones entre arrays de diferentes formas. NumPy automáticamente expande el array más pequeño para compatibilidad.
import numpy as np
# Ejemplo 1: arrays de diferentes formas
a = np.array([[1, 2, 3],
[4, 5, 6]])
b = np.array([10, 20, 30])
# b es "broadcast" para tener la misma forma que a
print(a + b)
# [[11 22 33]
# [14 25 36]]
# Ejemplo 2: escalar con array
arr = np.array([1, 2, 3, 4, 5])
print(arr * 10) # [10 20 30 40 50]
# Ejemplo 3: matriz 2D con vector
matriz = np.ones((3, 3))
vector = np.array([1, 2, 3])
print(matriz + vector)
# [[2 3 4]
# [2 3 4]
# [2 3 4]]
🧮 Álgebra Lineal con NumPy
import numpy as np
# Producto punto
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print(np.dot(a, b)) # 32
# Multiplicación de matrices
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
print(np.matmul(A, B))
# [[19 22]
# [43 50]]
# Determinante
print(np.linalg.det(A)) # -2.0
# Inversa
print(np.linalg.inv(A))
# [[-2. 1. ]
# [ 1.5 -0.5]]
# Autovalores
w, v = np.linalg.eig(A)
print(f"Autovalores: {w}")
print(f"Autovectores: {v}")
🎓 Proyecto Práctico: Análisis de Ventas
import numpy as np
# Simular datos de ventas de una tienda
np.random.seed(42)
dias = 30
productos = ["Electrónicos", "Ropa", "Alimentos", "Hogar"]
# Generar ventas aleatorias para cada producto
ventas = np.random.randint(1000, 5000, size=(dias, len(productos)))
ventas = ventas.astype(float)
# Agregar variación de precio por producto
precios = np.array([500.00, 80.00, 25.00, 150.00])
# Calcular receita diária
receita_diaria = ventas * precios
print("=" * 50)
print("📊 INFORME DE VENTAS - TIENDA MIX")
print("=" * 50)
# Receita total por producto
receita_por_producto = receita_diaria.sum(axis=0)
print("\n💰 Receita por Producto:")
for i, prod in enumerate(productos):
print(f" {prod}: $ {receita_por_producto[i]:,.2f}")
# Producto más vendido
producto_mas_vendido = productos[np.argmax(receita_por_producto)]
print(f"\n🏆 Producto más vendido: {producto_mas_vendido}")
# Media diária de ventas
ventas_media_dia = ventas.mean(axis=1)
print(f"\n📈 Media de ventas por día: {ventas_media_dia.mean():,.0f}")
# Día con maior receita
dia_maior_receita = np.argmax(receita_diaria.sum(axis=1)) + 1
receita_dia_max = receita_diaria.sum(axis=1).max()
print(f"\n📅 Melhor día: Día {dia_maior_receita} ($ {receita_dia_max:,.2f})")
# Desviación estándar de ventas (volatilidad)
volatilidad = ventas.std(axis=0)
print(f"\n📉 Volatilidad por producto:")
for i, prod in enumerate(productos):
print(f" {prod}: {volatilidad[i]:,.0f}")
🔗 Integración con Otras Bibliotecas
NumPy es la base del ecosistema de ciencia de datos de Python. Mira cómo se integra con las principales bibliotecas:
NumPy + Pandas
import numpy as np
import pandas as pd
# Crear DataFrame a partir de arrays NumPy
datos = np.random.randn(100, 3)
df = pd.DataFrame(datos, columns=['A', 'B', 'C'])
print(df.describe())
NumPy + Matplotlib
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)
plt.plot(x, y)
plt.title('Seno con NumPy')
plt.show()
NumPy + SciPy
from scipy import stats
import numpy as np
datos = np.array([23, 25, 28, 30, 32, 35, 38, 40])
media = np.mean(datos)
desvio = np.std(datos)
resultado = stats.normaltest(datos)
print(f"Media: {media:.2f}")
print(f"Test normalidad: {resultado}")
⚡ Consejos de Rendimiento
- ✅ Usa arrays NumPy en lugar de listas Python para operaciones numéricas
- ✅ Prefiere operaciones vectorizadas en lugar de bucles
for - ✅ Utiliza
np.where()para condicionales en arrays - ✅ Usa
@njit(Numba) para funciones que no pueden ser vectorizadas - ✅ Evita usar
append()en bucles - preasigna la memoria - ✅ Usa
viewen lugar decopycuando sea posible - ✅ Configura el dtype correcto para ahorrar memoria
- ❌ Evita convertir arrays NumPy a listas Python
🚀 Próximos Pasos
Ahora que dominas NumPy, el siguiente paso es explorar bibliotecas que lo utilizan como base:
- Pandas Python — manipulación y análisis de datos tabulares
- Matplotlib Python — creación de gráficos y visualizaciones
- Python para Principiantes — si estás empezando desde cero
¡NumPy es solo el comienzo de tu viaje en ciencia de datos con Python! Sigue practicando y explorando las infinitas posibilidades que esta poderosa biblioteca ofrece.