Imagen destacada del tutorial: NumPy - Operaciones Avanzadas con Arrays
Numpy

NumPy - Operaciones Avanzadas con Arrays

José Elías Romero Guanipa
02 Sep 2025

Domina las operaciones avanzadas con arrays de NumPy: reshaping, concatenación, indexación booleana, broadcasting y más.

numpy python arrays operaciones-avanzadas indexacion +2 más

¡Bienvenido al segundo tutorial de NumPy! En esta entrega aprenderás a manipular arrays de manera avanzada, dominando técnicas esenciales para el procesamiento eficiente de datos numéricos.

Objetivo: Aprender operaciones avanzadas con arrays de NumPy, incluyendo reshaping, concatenación, indexación sofisticada y broadcasting.

Índice

Reshaping de Arrays

Cambiar la forma de un array sin modificar sus datos:

import numpy as np

# Array original
arr = np.arange(12)
print("Array original (1D):", arr)
print("Forma:", arr.shape)

# Reshape a 2D
arr_2d = arr.reshape(3, 4)
print("\nReshape a 3x4:")
print(arr_2d)
print("Forma:", arr_2d.shape)

# Reshape a 3D
arr_3d = arr.reshape(2, 2, 3)
print("\nReshape a 2x2x3:")
print(arr_3d)
print("Forma:", arr_3d.shape)

Usos comunes de reshape

# Aplanar un array multidimensional
matriz = np.array([[1, 2, 3], [4, 5, 6]])
print("Matriz original:")
print(matriz)

aplanado = matriz.reshape(-1)  # -1 significa "inferir dimensión"
print("\nArray aplanado:", aplanado)

# Cambiar a vector columna
vector_columna = arr.reshape(-1, 1)
print("\nVector columna:")
print(vector_columna)
print("Forma:", vector_columna.shape)

Redimensionamiento automático

# Usando -1 para inferir dimensiones
arr = np.arange(24)

# NumPy infiere la dimensión faltante
arr_4x6 = arr.reshape(4, -1)
print("4 filas, columnas inferidas:", arr_4x6.shape)

arr_2x3x4 = arr.reshape(2, 3, -1)
print("2x3x?, ? inferido:", arr_2x3x4.shape)

Concatenación y Apilamiento

Combinar múltiples arrays:

a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])

print("Array A:")
print(a)
print("\nArray B:")
print(b)

Concatenación

# Concatenar horizontalmente (axis=1)
horizontal = np.concatenate((a, b), axis=1)
print("\nConcatenación horizontal:")
print(horizontal)

# Concatenar verticalmente (axis=0)
vertical = np.concatenate((a, b), axis=0)
print("\nConcatenación vertical:")
print(vertical)

Apilamiento

# Apilar verticalmente
vstack = np.vstack((a, b))
print("\nVertical stack:")
print(vstack)

# Apilar horizontalmente
hstack = np.hstack((a, b))
print("\nHorizontal stack:")
print(hstack)

# Apilar en profundidad
dstack = np.dstack((a, b))
print("\nDepth stack (3D):")
print(dstack)
print("Forma:", dstack.shape)

División de Arrays

Separar un array en múltiples partes:

arr = np.arange(12)
print("Array original:", arr)

# Dividir en partes iguales
partes = np.split(arr, 4)
print("\nDividido en 4 partes:")
for i, parte in enumerate(partes):
    print(f"Parte {i}: {parte}")

División en posiciones específicas

# Dividir en posiciones específicas
arr = np.arange(10)
print("Array:", arr)

# Dividir en [2, 5, 8]
partes = np.split(arr, [2, 5, 8])
print("\nDivisiones en posiciones [2, 5, 8]:")
for i, parte in enumerate(partes):
    print(f"Parte {i}: {parte}")

División de arrays 2D

matriz = np.arange(16).reshape(4, 4)
print("Matriz 4x4:")
print(matriz)

# Dividir verticalmente
vertical_split = np.vsplit(matriz, 2)
print("\nDivisión vertical:")
for i, parte in enumerate(vertical_split):
    print(f"Parte {i}:")
    print(parte)
    print()

# Dividir horizontalmente
horizontal_split = np.hsplit(matriz, 2)
print("División horizontal:")
for i, parte in enumerate(horizontal_split):
    print(f"Parte {i}:")
    print(parte)
    print()

Transposición y Manipulación de Ejes

Cambiar la orientación de los arrays:

matriz = np.array([[1, 2, 3], [4, 5, 6]])
print("Matriz original:")
print(matriz)
print("Forma:", matriz.shape)

# Transposición
transpuesta = matriz.T
print("\nTranspuesta:")
print(transpuesta)
print("Forma:", transpuesta.shape)

# Transposición con transpose()
transpuesta2 = np.transpose(matriz)
print("\nTranspuesta con transpose():")
print(transpuesta2)

Arrays 3D y transposición

arr_3d = np.arange(24).reshape(2, 3, 4)
print("Array 3D (2, 3, 4):")
print(arr_3d)

# Transposición cambiando el orden de ejes
trans_3d = np.transpose(arr_3d, (1, 0, 2))
print("\nTransposición (1, 0, 2):")
print(trans_3d)
print("Nueva forma:", trans_3d.shape)

Aplanamiento de arrays

arr_3d = np.arange(24).reshape(2, 3, 4)

# Aplanar completamente
aplanado = arr_3d.flatten()
print("Array aplanado:", aplanado)

# Aplanar en orden C (por filas)
ravel_c = arr_3d.ravel()
print("Ravel (orden C):", ravel_c)

# Aplanar en orden F (por columnas)
ravel_f = np.ravel(arr_3d, order='F')
print("Ravel (orden F):", ravel_f)

Indexación Avanzada

Técnicas sofisticadas para acceder a elementos:

Indexación con arrays de índices

arr = np.array([10, 20, 30, 40, 50])
indices = np.array([0, 2, 4])

print("Array:", arr)
print("Índices:", indices)
print("Elementos seleccionados:", arr[indices])

Indexación en múltiples dimensiones

matriz = np.arange(12).reshape(3, 4)
print("Matriz:")
print(matriz)

# Seleccionar elementos específicos
filas = np.array([0, 1, 2])
columnas = np.array([1, 2, 3])

print("Elementos en posiciones (0,1), (1,2), (2,3):")
print(matriz[filas, columnas])

Indexación Booleana

Usar condiciones para seleccionar elementos:

arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print("Array:", arr)

# Crear máscara booleana
mascara = arr > 5
print("Máscara (elementos > 5):", mascara)
print("Elementos seleccionados:", arr[mascara])

# Operaciones con máscaras
pares = arr[arr % 2 == 0]
print("Números pares:", pares)

multiplos_3 = arr[(arr % 3 == 0) & (arr > 3)]
print("Múltiplos de 3 mayores que 3:", multiplos_3)

Modificación condicional

arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print("Array original:", arr)

# Modificar elementos que cumplen condición
arr[arr < 5] = 0
print("Después de poner 0 a elementos < 5:", arr)

# Usar np.where para asignaciones condicionales
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
resultado = np.where(arr % 2 == 0, arr * 2, arr / 2)
print("Pares * 2, impares / 2:", resultado)

Broadcasting

Operaciones entre arrays de diferentes formas:

# Broadcasting básico
a = np.array([1, 2, 3])
b = np.array([[10], [20], [30]])

print("Array A (1D):", a)
print("Array B (2D):")
print(b)

# Broadcasting automático
resultado = a + b
print("\nResultado del broadcasting:")
print(resultado)

Reglas de Broadcasting

# Ejemplo 1: Escalares
arr = np.array([[1, 2, 3], [4, 5, 6]])
print("Array:")
print(arr)

escalar = 10
resultado = arr + escalar
print(f"\nArray + {escalar}:")
print(resultado)

# Ejemplo 2: Arrays con dimensiones compatibles
a = np.array([[1, 2, 3]])
b = np.array([[10], [20]])

print("\nArray A (1, 3):")
print(a)
print("Array B (2, 1):")
print(b)

resultado = a + b
print("\nBroadcasting A + B:")
print(resultado)

Casos donde el broadcasting falla

# Broadcasting incompatible
a = np.array([1, 2, 3])      # (3,)
b = np.array([10, 20])       # (2,)

try:
    resultado = a + b
except ValueError as e:
    print("Error de broadcasting:", e)

# Solución: reshape
b_reshaped = b.reshape(2, 1)  # (2, 1)
print("Array B reshaped:", b_reshaped.shape)

Copia vs Vista

Entender la diferencia entre copias y vistas de arrays:

arr_original = np.array([1, 2, 3, 4, 5])
print("Array original:", arr_original)

# Vista (no copia los datos)
vista = arr_original[1:4]
print("Vista:", vista)

# Modificar la vista afecta al original
vista[0] = 99
print("Después de modificar vista:")
print("Vista:", vista)
print("Original:", arr_original)

Creación explícita de copias

arr_original = np.array([1, 2, 3, 4, 5])

# Copia completa
copia = arr_original.copy()
print("Copia:", copia)

# Modificar copia no afecta original
copia[0] = 999
print("Después de modificar copia:")
print("Copia:", copia)
print("Original:", copia)

Métodos que devuelven vistas vs copias

arr = np.arange(12).reshape(3, 4)
print("Array original:")
print(arr)

# Operaciones que devuelven vistas
vista1 = arr[1:3, :]      # Vista
vista2 = arr[:, 1:3]      # Vista
vista3 = arr.T            # Vista
vista4 = arr.ravel()      # Vista (por defecto)

# Operaciones que devuelven copias
copia1 = arr.copy()       # Copia
copia2 = arr.flatten()    # Copia
copia3 = arr.reshape(6, 2)  # Vista (normalmente)

print("Vista reshape:", copia3.base is arr)  # True si es vista

Proyecto Práctico - Procesamiento de Imágenes

Vamos a crear un programa simple de procesamiento de imágenes usando arrays de NumPy:

import numpy as np

def crear_imagen_sintetica(ancho, alto):
    """Crea una imagen sintética con patrones"""
    # Crear coordenadas
    x = np.linspace(0, 10, ancho)
    y = np.linspace(0, 10, alto)
    X, Y = np.meshgrid(x, y)

    # Crear patrones
    patron1 = np.sin(X) * np.cos(Y)
    patron2 = np.exp(-(X-5)**2 - (Y-5)**2)

    # Combinar patrones
    imagen = (patron1 + patron2) * 127 + 128
    return np.clip(imagen, 0, 255).astype(np.uint8)

def aplicar_filtro(imagen, filtro):
    """Aplica un filtro simple a la imagen"""
    if filtro == 'blur':
        # Filtro de desenfoque simple
        kernel = np.ones((3, 3)) / 9
    elif filtro == 'sharpen':
        # Filtro de nitidez
        kernel = np.array([[-1, -1, -1],
                          [-1,  9, -1],
                          [-1, -1, -1]])
    elif filtro == 'edge':
        # Detector de bordes
        kernel = np.array([[-1, -1, -1],
                          [-1,  8, -1],
                          [-1, -1, -1]])
    else:
        return imagen

    # Aplicar convolución simple
    resultado = np.zeros_like(imagen, dtype=np.float32)

    for i in range(1, imagen.shape[0] - 1):
        for j in range(1, imagen.shape[1] - 1):
            region = imagen[i-1:i+2, j-1:j+2]
            resultado[i, j] = np.sum(region * kernel)

    return np.clip(resultado, 0, 255).astype(np.uint8)

def analizar_imagen(imagen):
    """Analiza estadísticas de la imagen"""
    print("=== ANÁLISIS DE IMAGEN ===")
    print(f"Dimensiones: {imagen.shape}")
    print(f"Tipo de datos: {imagen.dtype}")
    print(f"Rango de valores: {imagen.min()} - {imagen.max()}")
    print(f"Valor promedio: {imagen.mean():.2f}")
    print(f"Desviación estándar: {imagen.std():.2f}")

    # Histograma simple
    hist, bins = np.histogram(imagen.flatten(), bins=10, range=(0, 255))
    print("\nHistograma (10 bins):")
    for i, (count, bin_edge) in enumerate(zip(hist, bins[:-1])):
        print(".1f")

def main():
    print("=== PROCESAMIENTO DE IMÁGENES CON NUMPY ===\n")

    # Crear imagen sintética
    imagen = crear_imagen_sintetica(20, 20)
    print("Imagen original creada")
    analizar_imagen(imagen)

    # Aplicar filtros
    filtros = ['blur', 'sharpen', 'edge']

    for filtro in filtros:
        imagen_filtrada = aplicar_filtro(imagen, filtro)
        print(f"\n--- Filtro: {filtro.upper()} ---")
        analizar_imagen(imagen_filtrada)

        # Operaciones de manipulación
        print(f"\nManipulaciones para {filtro}:")
        print(f"  Invertida: rango {255 - imagen_filtrada.max()} - {255 - imagen_filtrada.min()}")
        print(f"  Brillo +50: rango {np.clip(imagen_filtrada + 50, 0, 255).min()} - {np.clip(imagen_filtrada + 50, 0, 255).max()}")
        print(f"  Contraste: std {np.clip(imagen_filtrada * 1.5, 0, 255).std():.2f}")

if __name__ == "__main__":
    main()

Próximos Pasos

¡Excelente progreso! Has dominado las operaciones avanzadas con arrays. Ahora puedes:

  1. Funciones Matemáticas y Estadísticas: Operaciones numéricas avanzadas
  2. NumPy para Ciencia de Datos: Integración con análisis de datos
  3. Optimización de Rendimiento: Técnicas para código más eficiente
  4. Integración con otras bibliotecas: Pandas, Matplotlib, SciPy

Tutoriales Recomendados

Conclusión

Las operaciones avanzadas con arrays son fundamentales para el procesamiento eficiente de datos en NumPy. Has aprendido a:

  • Cambiar la forma de los arrays con reshape
  • Combinar arrays mediante concatenación y apilamiento
  • Dividir arrays en partes manejables
  • Usar indexación sofisticada para acceder a datos específicos
  • Aplicar broadcasting para operaciones entre arrays de diferentes formas
  • Entender la diferencia entre copias y vistas

Practica estos conceptos aplicándolos a tus propios proyectos y verás cómo mejoran significativamente el rendimiento y la expresividad de tu código.

¡Sigue adelante en tu camino hacia el dominio de NumPy!


¡Continúa explorando las poderosas capacidades de NumPy!


💡 Tip Importante

📝 Mejores Prácticas para Operaciones con Arrays

  • Usa broadcasting cuando sea posible para evitar bucles explícitos
  • Entiende la diferencia entre vistas y copias para optimizar memoria
  • Utiliza indexación booleana para selecciones condicionales eficientes
  • Aprovecha reshape para cambiar dimensiones sin copiar datos
  • Documenta operaciones complejas con comentarios claros

📚 Recursos Recomendados:

¡Tu dominio de NumPy continúa creciendo. Sigue practicando y experimentando!

Toca los botones para interactuar

Comentarios

Comentarios

Inicia sesión para dejar un comentario.

No hay comentarios aún

Sé el primero en comentar este tutorial.

Tutoriales Relacionados

Descubre más tutoriales relacionados que podrían ser de tu interés

Imagen destacada del tutorial relacionado: Introducción a NumPy: La Base de la Computación Numérica en Python
Numpy

Introducción a NumPy: La Base de la Computación Numérica en Python

Aprende los fundamentos de NumPy, la biblioteca esencial para computación numérica en Python. Arrays, operaciones básicas y primeros pasos.

José Elías Romero Guanipa
01 Sep 2025
Imagen destacada del tutorial relacionado: NumPy - Operaciones Matemáticas y Estadísticas
Numpy

NumPy - Operaciones Matemáticas y Estadísticas

Domina las funciones matemáticas de NumPy: trigonometría, estadística, álgebra lineal y números aleatorios.

José Elías Romero Guanipa
03 Sep 2025
Imagen destacada del tutorial relacionado: NumPy Avanzado: Técnicas de Alto Rendimiento
Numpy

NumPy Avanzado: Técnicas de Alto Rendimiento

Domina las técnicas avanzadas de NumPy: arrays estructurados, optimización de memoria, ufuncs personalizadas y alto rendimiento.

José Elías Romero Guanipa
04 Sep 2025
Imagen destacada del tutorial relacionado: NumPy para Data Science: Análisis de Datos en la Práctica
Numpy

NumPy para Data Science: Análisis de Datos en la Práctica

Aplica NumPy en escenarios reales de data science: carga de datos, preprocesamiento, análisis estadístico y preparación para ML.

José Elías Romero Guanipa
05 Sep 2025
Foto de perfil del autor José Elías Romero Guanipa
José Elías Romero Guanipa
Autor

🌟 Nube de Etiquetas

Descubre temas populares en nuestros tutoriales

python
python 19 tutoriales
ciencia de datos
ciencia de datos 8 tutoriales
pandas
pandas 6 tutoriales
principiante
principiante 5 tutoriales
numpy
numpy 5 tutoriales
bases de datos
bases de datos 4 tutoriales
dataframe
dataframe 4 tutoriales
csv
csv 3 tutoriales
json
json 3 tutoriales
estadistica
estadistica 3 tutoriales
poo
poo 3 tutoriales
machine learning
machine learning 3 tutoriales
patrones diseño
patrones diseño 3 tutoriales
rendimiento
rendimiento 3 tutoriales
mysql
mysql 3 tutoriales
postgresql
postgresql 3 tutoriales
analisis de datos
analisis de datos 3 tutoriales
excepciones
excepciones 2 tutoriales
algoritmos
algoritmos 2 tutoriales
estructuras datos
estructuras datos 2 tutoriales
programación
programación 2 tutoriales
colaboracion
colaboracion 2 tutoriales
intermedio
intermedio 2 tutoriales
tutorial python
tutorial python 2 tutoriales
variables
variables 2 tutoriales

Las etiquetas más grandes y brillantes aparecen en más tutoriales

logo logo

©2024 ViveBTC