
NumPy - Operaciones Matemáticas y Estadísticas
Domina las funciones matemáticas de NumPy: trigonometría, estadística, álgebra lineal y números aleatorios.
¡Bienvenido al tutorial de funciones matemáticas de NumPy! Aquí aprenderás a utilizar las poderosas funciones matemáticas y estadísticas que hacen de NumPy una herramienta indispensable para científicos, ingenieros y analistas de datos.
Objetivo: Aprender a usar las funciones matemáticas universales, estadísticas, trigonométricas y de álgebra lineal de NumPy, junto con generación de números aleatorios.
Índice
- Funciones Universales (ufuncs)
- Funciones Trigonométricas
- Funciones Exponenciales y Logarítmicas
- Funciones Estadísticas
- Álgebra Lineal Básica
- Números Aleatorios
- Funciones de Redondeo y Aproximación
- Números Complejos
- Proyecto Práctico - Análisis Estadístico
- Próximos Pasos
- Conclusión
Funciones Universales (ufuncs)
Las ufuncs son funciones que operan elemento a elemento en arrays de NumPy:
import numpy as np
# Array de ejemplo
arr = np.array([1, 2, 3, 4, 5])
print("Array:", arr)
# Funciones aritméticas
print("Raíz cuadrada:", np.sqrt(arr))
print("Cuadrado:", np.square(arr))
print("Valor absoluto:", np.abs(arr - 3))
print("Seno:", np.sin(arr))
print("Exponencial:", np.exp(arr))
Ventajas de las ufuncs
# Comparación con bucles tradicionales
arr_grande = np.random.rand(1000000)
# Usando ufunc (eficiente)
%timeit np.sqrt(arr_grande)
# Usando comprensión de lista (menos eficiente)
%timeit [x**0.5 for x in arr_grande]
# Operaciones entre arrays
a = np.array([1, 2, 3, 4])
b = np.array([5, 6, 7, 8])
print("Suma:", np.add(a, b))
print("Resta:", np.subtract(a, b))
print("Multiplicación:", np.multiply(a, b))
print("División:", np.divide(a, b))
print("Máximo:", np.maximum(a, b))
print("Mínimo:", np.minimum(a, b))
Funciones Trigonométricas
NumPy proporciona todas las funciones trigonométricas estándar:
# Ángulos en radianes
angulos = np.array([0, np.pi/6, np.pi/4, np.pi/3, np.pi/2])
print("Ángulos (radianes):", angulos)
print("Ángulos (grados):", np.degrees(angulos))
# Funciones trigonométricas básicas
print("Seno:", np.sin(angulos))
print("Coseno:", np.cos(angulos))
print("Tangente:", np.tan(angulos))
# Funciones trigonométricas inversas
valores = np.array([0, 0.5, 1, np.sqrt(3)/2])
print("Arcoseno:", np.arcsin(valores))
print("Arcocoseno:", np.arccos(valores))
print("Arcotangente:", np.arctan(valores))
Aplicaciones prácticas
# Convertir coordenadas polares a cartesianas
radio = 5
angulo = np.pi/4
x = radio * np.cos(angulo)
y = radio * np.sin(angulo)
print(f"Coordenadas cartesianas: ({x:.2f}, {y:.2f})")
# Convertir coordenadas cartesianas a polares
x, y = 3, 4
radio = np.sqrt(x**2 + y**2)
angulo = np.arctan2(y, x)
print(f"Coordenadas polares: r={radio:.2f}, θ={np.degrees(angulo):.2f}°")
Funciones Exponenciales y Logarítmicas
Funciones para trabajar con exponenciales y logaritmos:
x = np.array([0.1, 0.5, 1, 2, 5, 10])
print("x:", x)
print("e^x:", np.exp(x))
print("2^x:", np.power(2, x))
print("ln(x):", np.log(x))
print("log10(x):", np.log10(x))
print("log2(x):", np.log2(x))
Funciones hiperbólicas
x = np.linspace(-2, 2, 9)
print("x:", x)
print("Seno hiperbólico:", np.sinh(x))
print("Coseno hiperbólico:", np.cosh(x))
print("Tangente hiperbólica:", np.tanh(x))
# Inversas hiperbólicas
y = np.array([0, 0.5, 1, 2])
print("Arcoseno hiperbólico:", np.arcsinh(y))
print("Arcocoseno hiperbólico:", np.arccosh(y + 1)) # y + 1 para valores >= 1
print("Arcotangente hiperbólico:", np.arctanh(y))
Funciones Estadísticas
NumPy ofrece funciones estadísticas completas:
datos = np.array([12, 15, 18, 22, 25, 28, 30, 35, 40, 45])
print("Datos:", datos)
print("Media:", np.mean(datos))
print("Mediana:", np.median(datos))
print("Desviación estándar:", np.std(datos))
print("Varianza:", np.var(datos))
print("Mínimo:", np.min(datos))
print("Máximo:", np.max(datos))
print("Rango:", np.ptp(datos)) # peak-to-peak
Estadísticas por ejes en arrays multidimensionales
matriz = np.random.randint(1, 100, (4, 5))
print("Matriz:")
print(matriz)
print("\nEstadísticas globales:")
print("Media total:", np.mean(matriz))
print("Suma total:", np.sum(matriz))
print("\nEstadísticas por filas (axis=1):")
print("Media por filas:", np.mean(matriz, axis=1))
print("Suma por filas:", np.sum(matriz, axis=1))
print("\nEstadísticas por columnas (axis=0):")
print("Media por columnas:", np.mean(matriz, axis=0))
print("Suma por columnas:", np.sum(matriz, axis=0))
Percentiles y cuantiles
datos = np.random.normal(100, 15, 1000) # Distribución normal
print("Estadísticas de distribución normal:")
print("Media:", np.mean(datos))
print("Mediana:", np.median(datos))
print("Desviación estándar:", np.std(datos))
# Percentiles
print("\nPercentiles:")
print("25th percentil:", np.percentile(datos, 25))
print("50th percentil (mediana):", np.percentile(datos, 50))
print("75th percentil:", np.percentile(datos, 75))
print("95th percentil:", np.percentile(datos, 95))
# Cuantiles
print("\nCuantiles:")
print("1st cuartil:", np.quantile(datos, 0.25))
print("2nd cuartil:", np.quantile(datos, 0.5))
print("3rd cuartil:", np.quantile(datos, 0.75))
Álgebra Lineal Básica
Operaciones matriciales con NumPy:
# Matrices de ejemplo
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
print("Matriz A:")
print(A)
print("\nMatriz B:")
print(B)
# Multiplicación matricial
print("\nA @ B (multiplicación matricial):")
print(A @ B)
print("\nUsando np.dot:")
print(np.dot(A, B))
# Producto elemento a elemento
print("\nA * B (elemento a elemento):")
print(A * B)
Operaciones matriciales avanzadas
A = np.array([[4, 2], [1, 3]])
print("Matriz A:")
print(A)
# Determinante
det = np.linalg.det(A)
print("Determinante:", det)
# Inversa
inv_A = np.linalg.inv(A)
print("\nInversa de A:")
print(inv_A)
# Verificar: A @ inv_A debería ser la identidad
print("\nA @ inv_A:")
print(A @ inv_A)
# Autovalores y autovectores
eigenvals, eigenvecs = np.linalg.eig(A)
print("\nAutovalores:", eigenvals)
print("Autovectores:")
print(eigenvecs)
Sistemas de ecuaciones lineales
# Sistema: 2x + y = 8
# x - y = 1
A = np.array([[2, 1], [1, -1]])
b = np.array([8, 1])
print("Matriz de coeficientes A:")
print(A)
print("Vector de constantes b:", b)
# Resolver sistema
x = np.linalg.solve(A, b)
print("Solución:", x)
# Verificar
print("Verificación A @ x:", A @ x)
Números Aleatorios
Generación de números aleatorios con NumPy:
# Configurar semilla para reproducibilidad
np.random.seed(42)
# Números aleatorios uniformes [0, 1)
aleatorios_uniformes = np.random.random(5)
print("Aleatorios uniformes [0,1):", aleatorios_uniformes)
# Números enteros aleatorios
enteros_aleatorios = np.random.randint(1, 101, 10) # 1 a 100
print("Enteros aleatorios 1-100:", enteros_aleatorios)
# Distribución normal
normales = np.random.normal(0, 1, 5) # media=0, std=1
print("Distribución normal (0,1):", normales)
# Distribución binomial
binomiales = np.random.binomial(10, 0.5, 5) # n=10, p=0.5
print("Distribución binomial (10,0.5):", binomiales)
Otras distribuciones importantes
# Distribución exponencial
exp_dist = np.random.exponential(2, 5) # lambda=2
print("Exponencial (lambda=2):", exp_dist)
# Distribución de Poisson
poisson_dist = np.random.poisson(3, 5) # lambda=3
print("Poisson (lambda=3):", poisson_dist)
# Distribución beta
beta_dist = np.random.beta(2, 5, 5) # alpha=2, beta=5
print("Beta (2,5):", beta_dist)
# Distribución gamma
gamma_dist = np.random.gamma(2, 2, 5) # shape=2, scale=2
print("Gamma (2,2):", gamma_dist)
Muestreo y permutaciones
# Elegir elementos aleatorios
poblacion = np.arange(1, 101)
muestra = np.random.choice(poblacion, size=10, replace=False)
print("Muestra sin reemplazo:", muestra)
# Permutación
arr = np.array([1, 2, 3, 4, 5])
permutado = np.random.permutation(arr)
print("Array original:", arr)
print("Permutación:", permutado)
# Barajar array in-place
arr_copy = arr.copy()
np.random.shuffle(arr_copy)
print("Array barajado:", arr_copy)
Funciones de Redondeo y Aproximación
Funciones para redondear y aproximar valores:
valores = np.array([1.234, 2.567, 3.891, 4.123, -5.678])
print("Valores originales:", valores)
# Redondeo al entero más cercano
print("round():", np.round(valores))
# Redondeo hacia abajo (floor)
print("floor():", np.floor(valores))
# Redondeo hacia arriba (ceil)
print("ceil():", np.ceil(valores))
# Truncar (eliminar decimales)
print("trunc():", np.trunc(valores))
# Redondeo a decimales específicos
print("round() a 2 decimales:", np.round(valores, 2))
print("round() a 1 decimal:", np.round(valores, 1))
Funciones de signo y comparación
valores = np.array([-3.7, -1.2, 0, 1.2, 3.7])
print("Valores:", valores)
print("sign():", np.sign(valores)) # -1, 0, 1
print("abs():", np.abs(valores)) # valor absoluto
# Comparaciones
a = np.array([1, 2, 3, 4, 5])
b = np.array([5, 4, 3, 2, 1])
print("a:", a)
print("b:", b)
print("a == b:", a == b)
print("a > b:", a > b)
print("a <= b:", a <= b)
Números Complejos
NumPy soporta números complejos de manera nativa:
# Crear números complejos
z1 = np.complex64(3 + 4j)
z2 = np.complex128(1 - 2j)
print("z1:", z1, "tipo:", type(z1))
print("z2:", z2, "tipo:", type(z2))
# Parte real e imaginaria
print("Parte real de z1:", z1.real)
print("Parte imaginaria de z1:", z1.imag)
# Conjugado
print("Conjugado de z1:", np.conj(z1))
# Magnitud y fase
print("Magnitud de z1:", np.abs(z1))
print("Fase de z1:", np.angle(z1))
Operaciones con números complejos
z1 = 3 + 4j
z2 = 1 - 2j
print("z1:", z1)
print("z2:", z2)
print("z1 + z2:", z1 + z2)
print("z1 * z2:", z1 * z2)
print("z1 / z2:", z1 / z2)
print("z1 ** 2:", z1 ** 2)
# Funciones complejas
z = 1 + 1j
print("sqrt(z):", np.sqrt(z))
print("exp(z):", np.exp(z))
print("log(z):", np.log(z))
Proyecto Práctico - Análisis Estadístico
Vamos a crear un programa completo de análisis estadístico:
import numpy as np
import matplotlib.pyplot as plt
def generar_datos_muestra(n=1000):
"""Genera datos de muestra con diferentes distribuciones"""
np.random.seed(42)
# Datos de alturas (distribución normal)
alturas = np.random.normal(170, 10, n)
# Datos de ingresos (distribución log-normal)
ingresos = np.random.lognormal(10, 0.5, n)
# Datos de calificaciones (distribución beta)
calificaciones = np.random.beta(7, 3, n) * 100
# Datos categóricos (género)
genero = np.random.choice(['M', 'F'], n, p=[0.48, 0.52])
return alturas, ingresos, calificaciones, genero
def calcular_estadisticas_basicas(datos, nombre):
"""Calcula estadísticas básicas de un conjunto de datos"""
print(f"\n=== ESTADÍSTICAS DE {nombre.upper()} ===")
print(f"Número de observaciones: {len(datos)}")
print(f"Media: {np.mean(datos):.2f}")
print(f"Mediana: {np.median(datos):.2f}")
print(f"Desviación estándar: {np.std(datos):.2f}")
print(f"Varianza: {np.var(datos):.2f}")
print(f"Mínimo: {np.min(datos):.2f}")
print(f"Máximo: {np.max(datos):.2f}")
print(f"Rango: {np.ptp(datos):.2f}")
# Percentiles
print(f"Percentil 25: {np.percentile(datos, 25):.2f}")
print(f"Percentil 75: {np.percentile(datos, 75):.2f}")
print(f"Rango intercuartílico: {np.percentile(datos, 75) - np.percentile(datos, 25):.2f}")
def analizar_correlacion(x, y, nombre_x, nombre_y):
"""Analiza la correlación entre dos variables"""
correlacion = np.corrcoef(x, y)[0, 1]
covarianza = np.cov(x, y)[0, 1]
print(f"\n=== CORRELACIÓN: {nombre_x} vs {nombre_y} ===")
print(f"Coeficiente de correlación: {correlacion:.4f}")
print(f"Covarianza: {covarianza:.4f}")
if abs(correlacion) < 0.3:
intensidad = "débil"
elif abs(correlacion) < 0.7:
intensidad = "moderada"
else:
intensidad = "fuerte"
if correlacion > 0:
direccion = "positiva"
else:
direccion = "negativa"
print(f"Correlación {intensidad} y {direccion}")
def analisis_por_grupos(datos, grupos, nombre_datos, nombre_grupos):
"""Realiza análisis por grupos"""
grupos_unicos = np.unique(grupos)
print(f"\n=== ANÁLISIS POR {nombre_grupos.upper()} ===")
for grupo in grupos_unicos:
datos_grupo = datos[grupos == grupo]
print(f"\n{nombre_grupos} {grupo}:")
print(f" N: {len(datos_grupo)}")
print(f" Media: {np.mean(datos_grupo):.2f}")
print(f" Desviación: {np.std(datos_grupo):.2f}")
def analisis_probabilistico(datos, nombre):
"""Análisis probabilístico básico"""
print(f"\n=== ANÁLISIS PROBABILÍSTICO: {nombre.upper()} ===")
# Pruebas de normalidad básicas
from scipy import stats
# Asimetría y curtosis
skewness = stats.skew(datos)
kurtosis = stats.kurtosis(datos)
print(f"Asimetría (skewness): {skewness:.4f}")
if skewness > 0:
print(" Distribución sesgada a la derecha")
elif skewness < 0:
print(" Distribución sesgada a la izquierda")
else:
print(" Distribución simétrica")
print(f"Curtosis: {kurtosis:.4f}")
if kurtosis > 0:
print(" Distribución leptocúrtica (colas pesadas)")
elif kurtosis < 0:
print(" Distribución platicúrtica (colas ligeras)")
else:
print(" Distribución mesocúrtica")
def main():
print("=== ANÁLISIS ESTADÍSTICO COMPLETO ===\n")
# Generar datos
alturas, ingresos, calificaciones, genero = generar_datos_muestra()
# Análisis básico de cada variable
calcular_estadisticas_basicas(alturas, "Alturas (cm)")
calcular_estadisticas_basicas(ingresos, "Ingresos ($)")
calcular_estadisticas_basicas(calificaciones, "Calificaciones")
# Análisis de correlaciones
analizar_correlacion(alturas, ingresos, "Alturas", "Ingresos")
analizar_correlacion(calificaciones, ingresos, "Calificaciones", "Ingresos")
analizar_correlacion(alturas, calificaciones, "Alturas", "Calificaciones")
# Análisis por grupos
analisis_por_grupos(alturas, genero, "Alturas", "Género")
analisis_por_grupos(ingresos, genero, "Ingresos", "Género")
analisis_por_grupos(calificaciones, genero, "Calificaciones", "Género")
# Análisis probabilístico
analisis_probabilistico(alturas, "Alturas")
analisis_probabilistico(ingresos, "Ingresos")
analisis_probabilistico(calificaciones, "Calificaciones")
print("\n=== RESUMEN EJECUTIVO ===")
print(f"Total de observaciones analizadas: {len(alturas)}")
print(".2f")
print(".2f")
print(".2f")
print(f"Proporción de hombres: {np.mean(genero == 'M'):.1%}")
print(f"Proporción de mujeres: {np.mean(genero == 'F'):.1%}")
if __name__ == "__main__":
main()
Próximos Pasos
¡Felicidades! Has dominado las funciones matemáticas y estadísticas de NumPy. Ahora puedes:
- NumPy Avanzado: Técnicas avanzadas de manipulación de arrays
- NumPy para Data Science: Integración con Pandas y análisis de datos
- Visualización: Crear gráficos con Matplotlib usando datos de NumPy
- Machine Learning: Preparar datos para algoritmos de ML
Tutoriales Recomendados
Conclusión
Las funciones matemáticas y estadísticas de NumPy son herramientas poderosas que te permiten realizar análisis complejos de manera eficiente. Has aprendido a:
- Utilizar funciones universales para operaciones vectorizadas
- Aplicar funciones trigonométricas, exponenciales y logarítmicas
- Calcular estadísticas descriptivas completas
- Realizar operaciones de álgebra lineal
- Generar números aleatorios de diversas distribuciones
- Trabajar con números complejos
Estas habilidades son fundamentales para cualquier trabajo en ciencia de datos, ingeniería, física, finanzas y muchas otras disciplinas.
¡Sigue practicando y aplicando estos conceptos en proyectos reales!
¡Tu dominio de NumPy continúa expandiéndose!
💡 Tip Importante
📝 Mejores Prácticas para Funciones Matemáticas
- Usa ufuncs siempre que sea posible para máxima eficiencia
- Configura semillas para reproducibilidad en números aleatorios
- Elige el tipo de dato apropiado para optimizar memoria y precisión
- Utiliza funciones estadísticas para análisis exploratorio de datos
- Combina operaciones para evitar bucles innecesarios
📚 Recursos Recomendados:
¡Las matemáticas nunca han sido tan poderosas y accesibles. Sigue explorando!
No hay comentarios aún
Sé el primero en comentar este tutorial.