🔢 NumPy Cheatsheet Completo 🔢
NumPy es la librería esencial para la computación científica en Python. Ofrece un objeto de matriz multidimensional (ndarray) y funciones para operar con estas matrices de forma eficiente.
1. 🌟 Conceptos Clave
ndarray(N-dimensional Array): El objeto principal de NumPy. Es una cuadrícula de valores del mismo tipo, indexada por una tupla de enteros no negativos. Puede ser 0-dimensional (escalar), 1-dimensional (vector), 2-dimensional (matriz), o de dimensiones superiores.- Vectorización: La capacidad de aplicar operaciones a un array completo de una sola vez, sin necesidad de bucles explícitos en Python. Esto se traduce en un código más conciso y mucho más rápido (escrito en C).
- Broadcasting: Un mecanismo que permite a NumPy realizar operaciones en arrays de diferentes formas (shapes).
- Tipos de Datos (dtypes): NumPy permite especificar el tipo de datos de los elementos de un array (ej.
int32,float64,bool).
2. 🛠️ Configuración Inicial
- Instalación:
pip install numpy # o conda install numpy # Si usas Anaconda - Importación:
import numpy as np # La convención estándar
3. 🚀 Creación de Arrays (ndarrays)
3.1. Desde Listas de Python
import numpy as np
arr1d = np.array([1, 2, 3]) # Array 1D
arr2d = np.array([[1, 2, 3], [4, 5, 6]]) # Array 2D (Matriz)
arr3d = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) # Array 3D
3.2. Arrays con Valores Iniciales Específicos
np.zeros(shape, dtype): Array lleno de ceros.zeros_1d = np.zeros(5) # [0., 0., 0., 0., 0.] zeros_2d = np.zeros((2, 3)) # [[0., 0., 0.], [0., 0., 0.]]np.ones(shape, dtype): Array lleno de unos.ones_2d = np.ones((2, 2)) # [[1., 1.], [1., 1.]]np.full(shape, fill_value, dtype): Array lleno de un valor específico.full_array = np.full((2, 2), 7) # [[7, 7], [7, 7]]np.empty(shape, dtype): Array con valores arbitrarios (depende de la memoria). Útil cuando el array se llenará inmediatamente.empty_array = np.empty((2, 3)) # Contenido aleatorionp.identity(n, dtype): Matriz identidad (cuadrada, diagonal de unos, el resto ceros).identity_matrix = np.identity(3) # [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]np.eye(N, M=None, k=0, dtype): Matriz con unos en una diagonal específica.diag_ones = np.eye(3, 4, k=1) # Matriz 3x4, unos en la diagonal 1 (arriba de la principal)
3.3. Arrays con Rangos de Valores
np.arange(start, stop, step, dtype): Similar arange()de Python, pero devuelve unndarray.range_array = np.arange(0, 10, 2) # [0, 2, 4, 6, 8]np.linspace(start, stop, num, endpoint=True, retstep=False, dtype): Valores espaciados uniformemente en un intervalo.linear_space = np.linspace(0, 1, 5) # [0., 0.25, 0.5, 0.75, 1.]
4. ℹ️ Atributos del Array
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.ndim) # 2 (Número de dimensiones)
print(arr.shape) # (2, 3) (Tupla de dimensiones: filas, columnas)
print(arr.size) # 6 (Número total de elementos)
print(arr.dtype) # int64 (Tipo de datos de los elementos)
print(arr.itemsize) # 8 (Tamaño en bytes de cada elemento)
5. 🔎 Indexación y Slicing
5.1. Indexación Básica (Acceso por Posición)
- Similar a las listas de Python.
- Para arrays 2D, se usa
[fila, columna].
arr = np.array([10, 20, 30, 40, 50])
print(arr[0]) # 10
print(arr[-1]) # 50
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(arr2d[0, 0]) # 1 (fila 0, columna 0)
print(arr2d[1, 2]) # 6 (fila 1, columna 2)
5.2. Slicing (Rebanado)
[start:end:step]
arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
print(arr[2:7]) # [2, 3, 4, 5, 6]
print(arr[:5]) # [0, 1, 2, 3, 4]
print(arr[7:]) # [7, 8, 9]
print(arr[::2]) # [0, 2, 4, 6, 8] (cada 2 elementos)
print(arr[::-1]) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] (invertido)
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(arr2d[:, 1]) # [2, 5, 8] (todas las filas, columna 1)
print(arr2d[0:2, :]) # [[1, 2, 3], [4, 5, 6]] (filas 0 y 1, todas las columnas)
print(arr2d[::, ::-1]) # Todas las filas, columnas invertidas
5.3. Indexación Booleana
- Selecciona elementos basados en una condición booleana.
arr = np.array([1, 2, 3, 4, 5, 6])
mask = (arr > 3) # [False, False, False, True, True, True]
print(arr[mask]) # [4, 5, 6]
print(arr[arr % 2 == 0]) # [2, 4, 6] (solo los pares)
5.4. Indexación “Fancy”
- Selecciona elementos usando un array de índices.
arr = np.array([10, 20, 30, 40, 50])
indices = [0, 2, 4]
print(arr[indices]) # [10, 30, 50]
arr2d = np.array([[1, 2], [3, 4], [5, 6]])
rows = np.array([0, 2])
cols = np.array([1, 0])
print(arr2d[rows, cols]) # [2, 5] (selecciona (0,1) y (2,0))
6. ➕ Operaciones con Arrays
6.1. Operaciones Aritméticas Elemento a Elemento
- Suman, restan, multiplican, etc. arrays con la misma forma, o un array con un escalar (broadcasting).
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print(a + b) # [5, 7, 9]
print(a * 2) # [2, 4, 6]
print(a / b) # [0.25, 0.4, 0.5]
print(a ** 2) # [1, 4, 9]
6.2. Funciones Universales (ufuncs)
- Funciones que operan elemento a elemento en arrays (ej.
np.sqrt,np.exp,np.log,np.sin).
arr = np.array([1, 4, 9])
print(np.sqrt(arr)) # [1., 2., 3.]
print(np.exp(arr)) # [2.718..., 54.598..., 8103.08...]
6.3. Agregaciones (Funciones Reductoras)
- Calculan un único valor a partir de los elementos de un array.
- Pueden operar sobre todo el array o a lo largo de un eje (
axis).
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(np.sum(arr)) # 21 (suma de todos los elementos)
print(arr.sum()) # 21 (método del array)
print(arr.sum(axis=0)) # [5, 7, 9] (suma por columnas)
print(arr.sum(axis=1)) # [6, 15] (suma por filas)
print(np.min(arr)) # 1
print(np.max(arr)) # 6
print(np.mean(arr)) # 3.5 (promedio)
print(np.std(arr)) # Desviación estándar
print(np.argmin(arr)) # 0 (índice del mínimo global, aplanado)
print(np.argmax(arr, axis=1)) # [2, 2] (índice del máximo por fila)
7. 📏 Reshaping y Reorganización
-
reshape(shape): Cambia la forma del array sin cambiar sus datos.arr = np.arange(9) # [0, 1, 2, 3, 4, 5, 6, 7, 8] reshaped = arr.reshape((3, 3)) # [[0, 1, 2], [3, 4, 5], [6, 7, 8]]- Puedes usar
-1para que NumPy infiera una dimensión.reshaped_auto = arr.reshape(3, -1) # [[0, 1, 2], [3, 4, 5], [6, 7, 8]] (3 filas, 3 columnas auto)
- Puedes usar
-
ravel()/flatten(): Devuelven una copia aplanada (1D) del array.flatten()siempre devuelve una copia,ravel()puede devolver una vista.print(reshaped.ravel()) # [0, 1, 2, 3, 4, 5, 6, 7, 8] -
T(Transpuesta): Intercambia filas y columnas.matrix = np.array([[1, 2], [3, 4]]) print(matrix.T) # [[1, 3], [2, 4]] ```* **`np.newaxis`**: Añade una nueva dimensión al array. ```python arr = np.array([1, 2, 3]) row_vector = arr[np.newaxis, :] # [[1, 2, 3]] (1 fila, 3 columnas) col_vector = arr[:, np.newaxis] # [[1], [2], [3]] (3 filas, 1 columna)
8. 📊 Combinación y División de Arrays
8.1. Combinación (Concatenación)
np.concatenate((arr1, arr2), axis): Une arrays a lo largo de un eje existente.a = np.array([[1, 2], [3, 4]]) b = np.array([[5, 6], [7, 8]]) print(np.concatenate((a, b), axis=0)) # Unión vertical # [[1, 2], [3, 4], [5, 6], [7, 8]] print(np.concatenate((a, b), axis=1)) # Unión horizontal # [[1, 2, 5, 6], [3, 4, 7, 8]]np.vstack((arr1, arr2)): Apila arrays verticalmente (por filas).print(np.vstack((a, b))) # Igual que concatenate(axis=0)np.hstack((arr1, arr2)): Apila arrays horizontalmente (por columnas).print(np.hstack((a, b))) # Igual que concatenate(axis=1)
8.2. División
np.split(arr, indices_or_sections, axis): Divide un array en múltiples sub-arrays.arr = np.arange(9) split_arr = np.split(arr, 3) # Divide en 3 partes iguales # [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])] arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) split_rows = np.split(arr2d, [1, 2], axis=0) # Divide por filas después de índice 1 y 2 # [array([[1, 2, 3]]), array([[4, 5, 6]]), array([[7, 8, 9]])]np.vsplit(arr, indices_or_sections): Divide verticalmente.np.hsplit(arr, indices_or_sections): Divide horizontalmente.
9. 📐 Álgebra Lineal
NumPy tiene un submódulo linalg para operaciones de álgebra lineal.
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
# Producto punto de matrices (multiplicación matricial)
print(a @ b) # Python 3.5+
print(np.dot(a, b)) # Equivalente
# [[19, 22], [43, 50]]
# Inversa de una matriz
print(np.linalg.inv(a))
# [[-2., 1.], [1.5, -0.5]]
# Determinante de una matriz
print(np.linalg.det(a)) # -2.0
# Valores propios y vectores propios
eigenvalues, eigenvectors = np.linalg.eig(a)
print("Valores propios:", eigenvalues)
print("Vectores propios:", eigenvectors)
# Producto cruz (solo para 3D)
v1 = np.array([1, 2, 3])
v2 = np.array([4, 5, 6])
print(np.cross(v1, v2)) # [-3, 6, -3]
10. 🎲 Generación de Números Aleatorios
El submódulo np.random es para esto.
# Semilla para reproducibilidad
np.random.seed(42)
# Números flotantes uniformemente distribuidos entre 0.0 y 1.0
print(np.random.rand(3)) # [0.374..., 0.950..., 0.731...] (1D)
print(np.random.rand(2, 2)) # [[..., ...], [..., ...]] (2D)
# Números flotantes de una distribución normal estándar (media 0, varianza 1)
print(np.random.randn(3)) # [0.496..., -0.119..., 0.671...]
# Enteros aleatorios en un rango [low, high)
print(np.random.randint(low=0, high=10, size=5)) # 5 enteros entre 0 y 9
# Selección aleatoria de elementos de un array
elements = [1, 2, 3, 4, 5]
print(np.random.choice(elements, size=3, replace=False)) # 3 elementos únicos
11. 💾 Entrada/Salida (File I/O)
11.1. Guardar y Cargar Arrays Binarios (.npy, .npz)
np.save(filename, arr): Guarda un solo array en formato binario NumPy (.npy).np.load(filename): Carga un array desde un archivo.npy.np.savez(filename, arr1=arr1, arr2=arr2): Guarda múltiples arrays en un archivo comprimido (.npz).np.load(filename)['arr1']: Carga un array específico de un archivo.npz.
my_array = np.array([1, 2, 3, 4, 5])
np.save('my_array.npy', my_array)
loaded_array = np.load('my_array.npy')
print(loaded_array)
# Borrar archivos (para cleanup si es un script)
# import os
# os.remove('my_array.npy')
11.2. Guardar y Cargar desde Archivos de Texto (.txt, .csv)
np.savetxt(filename, arr, fmt='%.18e', delimiter=' '): Guarda un array en un archivo de texto (CSV por defecto).fmt: Formato de escritura (ej.'%d'para enteros,'%.2f'para flotantes con 2 decimales).delimiter: Separador de columnas.
np.loadtxt(filename, dtype=float, delimiter=None): Carga datos desde un archivo de texto.
data = np.array([[1.1, 2.2], [3.3, 4.4]])
np.savetxt('data.csv', data, delimiter=',', fmt='%.1f')
loaded_data = np.loadtxt('data.csv', delimiter=',')
print(loaded_data)
12. 💡 Buenas Prácticas y Consejos
- Vectorización: Siempre que sea posible, utiliza operaciones vectorizadas de NumPy en lugar de bucles de Python para un rendimiento superior.
- Dimensiones (Shape): Entender las dimensiones de tus arrays (
.shape) es crucial para operaciones de broadcasting, concatenación y otras manipulaciones. - In-place vs. Copy: Muchas operaciones de NumPy devuelven una nueva copia del array. Otras (como
arr += 1) modifican el array in-place. Tenlo en cuenta para evitar efectos secundarios no deseados. dtype: Especificar eldtypeadecuado puede ahorrar memoria y mejorar el rendimiento, especialmente con arrays grandes.- Broadcasting: Comprender cómo funciona el broadcasting te permite escribir código más conciso y eficiente. NumPy “estira” implícitamente arrays más pequeños para que coincidan con la forma de los arrays más grandes.
- Documentación: La documentación oficial de NumPy es excelente y es tu mejor recurso para funciones y detalles específicos.
Este cheatsheet te proporciona una referencia completa y concisa de NumPy, cubriendo sus conceptos esenciales, la creación y manipulación de arrays, operaciones clave de álgebra lineal y generación de números aleatorios. Es una herramienta fundamental para cualquier trabajo con datos numéricos en Python.