Introducción a NumPy: arrays y operaciones
Introducción
NumPy (Numerical Python) es una de las bibliotecas más importantes del ecosistema científico de Python. Proporciona soporte para trabajar con arrays multidimensionales de manera eficiente, además de incluir funciones matemáticas de alto nivel. NumPy es fundamental para el análisis de datos, la computación científica y forma la base de muchas otras bibliotecas populares como Pandas, SciPy y Matplotlib. En este artículo, aprenderemos los conceptos básicos de NumPy, cómo crear y manipular arrays, y realizar operaciones fundamentales con ellos.
Instalación de NumPy
Antes de comenzar, necesitamos instalar NumPy. Abre tu terminal o símbolo del sistema y ejecuta:
pip install numpy
Importación de NumPy
Por convención, NumPy se importa con el alias np
:
import numpy as np
Arrays de NumPy
Un array de NumPy es una estructura de datos que contiene elementos del mismo tipo, organizados en una rejilla multidimensional. La principal diferencia con las listas de Python es que los arrays de NumPy son más eficientes en términos de memoria y velocidad para operaciones matemáticas.
Creación de arrays
Hay varias formas de crear arrays en NumPy:
A partir de listas de Python
# Array unidimensional
array_1d = np.array([1, 2, 3, 4, 5])
print(array_1d)
# Resultado: [1 2 3 4 5]
# Array bidimensional (matriz)
array_2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(array_2d)
# Resultado:
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
Mediante funciones específicas
# Array de ceros
ceros = np.zeros((3, 4)) # Matriz de 3x4 con ceros
print(ceros)
# Array de unos
unos = np.ones((2, 3)) # Matriz de 2x3 con unos
print(unos)
# Array con un valor específico
valor_fijo = np.full((2, 2), 5) # Matriz 2x2 con el valor 5
print(valor_fijo)
# Array con valores aleatorios entre 0 y 1
aleatorios = np.random.random((2, 3))
print(aleatorios)
# Array con enteros aleatorios en un rango
enteros_aleatorios = np.random.randint(1, 10, size=(3, 3))
print(enteros_aleatorios)
Secuencias y rangos
# Secuencia con paso constante
secuencia = np.arange(0, 10, 2) # Valores de 0 a 10 (exclusivo) con paso 2
print(secuencia) # [0 2 4 6 8]
# Secuencia con número específico de elementos
linspace = np.linspace(0, 1, 5) # 5 valores equidistantes entre 0 y 1
print(linspace) # [0. 0.25 0.5 0.75 1. ]
Propiedades de los arrays
Los arrays de NumPy tienen varias propiedades útiles:
# Crear un array de ejemplo
arr = np.array([[1, 2, 3], [4, 5, 6]])
# Dimensiones
print(f"Dimensiones: {arr.ndim}") # 2 (bidimensional)
# Forma (filas, columnas)
print(f"Forma: {arr.shape}") # (2, 3)
# Tamaño (número total de elementos)
print(f"Tamaño: {arr.size}") # 6
# Tipo de datos
print(f"Tipo de datos: {arr.dtype}") # int64 (por defecto)
Indexación y rebanado
Al igual que con las listas, podemos acceder a elementos específicos de un array:
arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
# Acceder a un elemento (fila, columna)
print(arr[0, 1]) # 2 (primera fila, segunda columna)
# Acceder a una fila completa
print(arr[1]) # [5 6 7 8] (segunda fila)
# Rebanado: [inicio:fin:paso]
print(arr[0:2, 1:3])
# [[2 3]
# [6 7]]
# Elementos no consecutivos
print(arr[0:3:2, 0:4:2])
# [[1 3]
# [9 11]]
Operaciones con arrays
Una de las grandes ventajas de NumPy es la capacidad de realizar operaciones matemáticas de forma vectorizada, lo que significa que pueden aplicarse a todo el array sin necesidad de bucles explícitos.
Operaciones aritméticas
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# Suma
print(a + b) # [5 7 9]
# Resta
print(a - b) # [-3 -3 -3]
# Multiplicación (elemento a elemento)
print(a * b) # [4 10 18]
# División
print(a / b) # [0.25 0.4 0.5 ]
# Potencia
print(a ** 2) # [1 4 9]
Operaciones con escalar
# Multiplicación por escalar
print(a * 2) # [2 4 6]
# Suma con escalar
print(a + 10) # [11 12 13]
Funciones universales (ufuncs)
NumPy proporciona numerosas funciones que operan elemento a elemento:
# Funciones trigonométricas
angulos = np.array([0, np.pi/2, np.pi])
print(np.sin(angulos)) # [0.0, 1.0, 0.0]
# Exponencial y logaritmo
valores = np.array([1, 2, 3])
print(np.exp(valores)) # [2.71828183, 7.3890561, 20.08553692]
print(np.log(valores)) # [0.0, 0.69314718, 1.09861229]
# Raíz cuadrada
print(np.sqrt(valores)) # [1.0, 1.41421356, 1.73205081]
# Redondeo
decimales = np.array([1.1, 1.5, 1.9])
print(np.floor(decimales)) # [1. 1. 1.]
print(np.ceil(decimales)) # [2. 2. 2.]
print(np.round(decimales)) # [1. 2. 2.]
Operaciones estadísticas
NumPy incluye funciones estadísticas básicas:
datos = np.array([1, 2, 3, 4, 5])
# Suma de todos los elementos
print(np.sum(datos)) # 15
# Media
print(np.mean(datos)) # 3.0
# Desviación estándar
print(np.std(datos)) # ~1.41
# Mínimo y máximo
print(np.min(datos)) # 1
print(np.max(datos)) # 5
Para arrays multidimensionales, podemos especificar el eje (axis) sobre el que aplicar la operación:
matriz = np.array([[1, 2, 3], [4, 5, 6]])
# Suma por filas (axis=1)
print(np.sum(matriz, axis=1)) # [6 15]
# Media por columnas (axis=0)
print(np.mean(matriz, axis=0)) # [2.5 3.5 4.5]
Operaciones de algebra lineal
NumPy tiene soporte para operaciones de álgebra lineal:
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
# Producto matricial
c = np.matmul(a, b)
print(c)
# [[19 22]
# [43 50]]
# O usando el operador @
c = a @ b
print(c) # Mismo resultado que arriba
# Determinante
print(np.linalg.det(a)) # -2.0
# Inversa de una matriz
print(np.linalg.inv(a))
# [[-2. 1. ]
# [ 1.5 -0.5]]
# Autovalores y autovectores
autovalores, autovectores = np.linalg.eig(a)
print(f"Autovalores: {autovalores}")
print(f"Autovectores: {autovectores}")
Transformaciones de forma
Podemos cambiar la forma de un array sin modificar sus datos:
arr = np.arange(12) # [0 1 2 3 4 5 6 7 8 9 10 11]
# Cambiar a forma 3x4
matriz = arr.reshape(3, 4)
print(matriz)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
# Transponer una matriz (intercambiar filas y columnas)
print(matriz.T)
# [[ 0 4 8]
# [ 1 5 9]
# [ 2 6 10]
# [ 3 7 11]]
# Aplanar una matriz
print(matriz.flatten()) # [0 1 2 3 4 5 6 7 8 9 10 11]
Caso práctico: Análisis de temperaturas
Veamos un ejemplo práctico que combina varias operaciones de NumPy:
# Temperaturas diarias en grados Celsius durante una semana
temperaturas = np.array([
[22, 24, 23, 26, 25, 28, 27], # Ciudad A
[20, 22, 21, 23, 24, 25, 24], # Ciudad B
[30, 32, 31, 33, 34, 35, 34] # Ciudad C
])
# Temperatura promedio por ciudad
prom_ciudad = np.mean(temperaturas, axis=1)
print(f"Temperatura promedio por ciudad: {prom_ciudad}")
# Temperatura promedio por día
prom_dia = np.mean(temperaturas, axis=0)
print(f"Temperatura promedio por día: {prom_dia}")
# Ciudad más calurosa (índice)
ciudad_calurosa = np.argmax(prom_ciudad)
print(f"La ciudad más calurosa es la {ciudad_calurosa + 1}ª")
# Día más frío (índice)
dia_frio = np.argmin(prom_dia)
print(f"El día más frío fue el {dia_frio + 1}º")
# Convertir a Fahrenheit (F = C * 9/5 + 32)
temperaturas_f = temperaturas * 9/5 + 32
print("Temperaturas en Fahrenheit:")
print(temperaturas_f)
# Cuántos días superaron los 30°C en cada ciudad
dias_calurosos = np.sum(temperaturas > 30, axis=1)
print(f"Días con más de 30°C por ciudad: {dias_calurosos}")
Resumen
NumPy es una biblioteca fundamental para la computación numérica en Python. Proporciona estructuras de datos eficientes (arrays) que permiten realizar operaciones matemáticas vectorizadas. Hemos aprendido a crear arrays, acceder a sus elementos, y realizar diversas operaciones como cálculos aritméticos, estadísticos y de álgebra lineal. Estas capacidades convierten a NumPy en una herramienta esencial para cualquier tarea de análisis de datos o computación científica. En el siguiente artículo, exploraremos Pandas, una biblioteca construida sobre NumPy que facilita aún más el análisis y manipulación de datos estructurados.