NumPy

Numpy

Tutorial Numpy: Indexación y segmentación en Numpy

Numpy indexación y segmentación: Aprende técnicas avanzadas de Numpy para indexar y segmentar arrays de manera eficiente. Incluye ejemplos de fancy indexing, boolean indexing y slicing.

¿Qué es la indexación en el contexto de Arrays de Numpy?

La indexación en el contexto de Arrays de Numpy se refiere al proceso de acceder y manipular elementos individuales o subconjuntos más grandes de un array. 

A diferencia de las listas en Python, donde la indexación se hace mediante enteros que representan posiciones concretas, Numpy permite un nivel de flexibilidad y potencia mucho mayor. Algunos de los aspectos clave de la indexación en Numpy incluyen:

  • Indexación basada en enteros: Similar a las listas de Python, los arrays de Numpy pueden ser indexados utilizando enteros. Por ejemplo, arr[0] accederá al primer elemento de arr.
  • Indexación multidimensional: Los arrays pueden tener múltiples dimensiones, y se puede acceder a elementos individuales aplicando múltiples índices. Por ejemplo, en un array de dos dimensiones arr, se puede acceder al elemento de la primera fila y segunda columna con arr[0,1].
  • Fancy indexing: Permite usar listas o arrays de enteros como índices para seleccionar múltiples elementos no contiguos en un array. Por ejemplo, arr[[0, 2, 3]] accederá a los elementos en las posiciones 0, 2 y 3 de arr.
  • Boolean indexing: Utiliza máscaras booleanas para indexar arrays. Esto es útil cuando se quiere seleccionar elementos que cumplen una condición específica. Por ejemplo, arr[arr > 5] seleccionará todos los elementos de arr que son mayores que 5.
import numpy as np

# Ejemplos de indexación
arr = np.array([10, 20, 30, 40, 50])

# Indexación simple
print(arr[0])  # Output: 10

# Fancy indexing
indices = [1, 3]
print(arr[indices])  # Output: [20 40]

# Boolean indexing
print(arr[arr > 30])  # Output: [40 50]
  • Slicing: Aunque se trata con más detalle en otras secciones, es importante mencionar que la segmentación (o slicing) es un caso especial de indexación donde se usan operadores de rango para seleccionar subconjuntos continuos de datos.
# Segmentación o slicing
arr = np.array([1, 2, 3, 4, 5, 6])
print(arr[1:4])  # Output: [2 3 4]

La indexación avanzada de Numpy, que incluye fancy indexing y boolean indexing, permite realizar operaciones complejas y potentes para análisis de datos y operaciones numéricas de manera eficiente y con un código más limpio y legible.

Todas las formas posibles de indexación de Arrays con Numpy

Numpy ofrece múltiples formas de indexar sus arrays, proporcionando una gran flexibilidad para acceder y manipular datos. 

A continuación, se describen todas las formas posibles de indexación de arrays en Numpy.

Indexación por enteros

La forma más básica de indexación es utilizando enteros, que funciona de manera similar a las listas de Python.

import numpy as np

arr = np.array([5, 10, 15, 20, 25])
print(arr[0])  # Output: 5
print(arr[4])  # Output: 25

En arrays multidimensionales, los enteros pueden usarse para acceder a elementos específicos.

arr_2d = np.array([[1, 2], [3, 4], [5, 6]])
print(arr_2d[0, 1])  # Output: 2
print(arr_2d[2, 0])  # Output: 5

Slicing

El slicing o segmentación permite extraer subconjuntos continuos de datos.

arr = np.array([10, 20, 30, 40, 50])
print(arr[1:4])  # Output: [20 30 40]
print(arr[:3])   # Output: [10 20 30]
print(arr[::2])  # Output: [10 30 50]

En arrays multidimensionales, se pueden aplicar slices por cada dimensión.

arr_2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(arr_2d[1:, :2])  # Output: [[4 5] [7 8]]
print(arr_2d[:, 1:])   # Output: [[2 3] [5 6] [8 9]]

Fancy indexing

Fancy indexing permite utilizar listas o arrays de enteros como índices para seleccionar elementos no contiguos.

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

Para arrays multidimensionales, fancy indexing también es posible.

arr_2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
row_indices = [0, 2]
col_indices = [1, 2]
print(arr_2d[row_indices, col_indices])  # Output: [2 9]

Boolean indexing

Boolean indexing utiliza máscaras booleanas para seleccionar elementos que cumplen ciertas condiciones.

arr = np.array([1, 2, 3, 4, 5, 6])
mask = arr > 3
print(arr[mask])  # Output: [4 5 6]
print(arr[arr % 2 == 0])  # Output: [2 4 6]

En arrays multidimensionales, la máscara se puede aplicar a todo el array o a un eje específico.

arr_2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
mask = arr_2d > 5
print(arr_2d[mask])  # Output: [6 7 8 9]

Indexación combinada

Es posible combinar diferentes tipos de indexación en una sola operación para una mayor flexibilidad.

arr_2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(arr_2d[1:, [0, 2]])  # Output: [[4 6] [7 9]]

mask = (arr_2d % 2 == 0)
print(arr_2d[mask])  # Output: [2 4 6 8]

Indexación con np.newaxis y Ellipsis

El objeto np.newaxis y el literal ... (Ellipsis) permiten alterar el número de dimensiones.

arr = np.array([1, 2, 3])
print(arr[:, np.newaxis])  # Output: [[1] [2] [3]]

arr_3d = arr[np.newaxis, np.newaxis, :]
print(arr_3d.shape)  # Output: (1, 1, 3)

arr_2d = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
print(arr_2d[..., 1])  # Output: [2 4 6 8]

Estas diferentes formas de indexación permiten una manipulación de datos extremadamente poderosa y flexible en Numpy, optimizando el rendimiento y la claridad del código.

¿Qué es la segmentación en el contexto de Arrays de Numpy?

En el contexto de arrays de Numpy, la segmentación (también conocida como slicing) es una técnica que permite extraer subconjuntos continuos de elementos de un array. A diferencia de la indexación, que accede a elementos individuales (o un grupo de elementos no contiguos mediante fancy indexing), la segmentación permite trabajar con rangos de elementos, proporcionando una herramienta extremadamente útil para manipular datos de manera eficiente.

Para realizar la segmentación de un array, se utilizan los operadores de rango :, que tienen la siguiente sintaxis básica:

arr[start:stop:step]
  • start: El índice de inicio (inclusive).
  • stop: El índice de fin (exclusive).
  • step: El intervalo de segmentación.

Si se omiten start, stop o step, se utilizan los valores predeterminados 0, tamaño del array y 1, respectivamente.

Ejemplos de segmentación

Segmentar los primeros n elementos de un array unidimensional:

import numpy as np

arr = np.array([0, 1, 2, 3, 4, 5])
print(arr[:3])  # Output: [0 1 2]

Segmentar de un índice a otro con un paso específico:

print(arr[1:5:2])  # Output: [1 3]
print(arr[::2])   # Output: [0 2 4]

En el caso de arrays multidimensionales, la segmentación se puede aplicar a cada una de las dimensiones por separado:

arr_2d = np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]])
print(arr_2d[:2, 1:])  # Output: [[20 30] [50 60]]
print(arr_2d[:, ::2])  # Output: [[10 30] [40 60] [70 90]]

Segmentación inversa y pasos negativos

La segmentación admite también el uso de pasos negativos para acceder a los elementos en orden inverso:

print(arr[::-1])  # Output: [5 4 3 2 1 0]
print(arr_2d[:, ::-1])  # Output: [[30 20 10] [60 50 40] [90 80 70]]

Esta propiedad es especialmente útil para invertir arrays o acceder cómodamente a los últimos elementos.

Uso conjunto con boolean arrays y fancy indexing

La segmentación puede ser combinada con boolean indexing y fancy indexing para realizar selecciones complejas de datos, proporcionando una capa adicional de flexibilidad:

mask = arr > 2
print(arr[mask][1:3])  # Output: [4 5]

indices = [0, 2, 4]
print(arr[indices][::2])  # Output: [0 4]

Esta capacidad de combinar diferentes metodologías de selección es una de las fortalezas clave de Numpy, permitiendo la implementación de operaciones sofisticadas en una sola línea de código.

La segmentación en Numpy es una técnica esencial para el trabajo con arrays, permitiendo operaciones eficientes y concisas sobre grandes volúmenes de datos y facilitando tareas comunes en análisis de datos y procesamiento numérico.

Todas las formas posibles de segmentación de Arrays con Numpy

La segmentación de arrays en Numpy permite extraer subconjuntos continuos de elementos. 

A continuación, se describen detalladamente las diversas formas de segmentación junto con sus respectivas aplicaciones.

Segmentación básica

La segmentación básica utiliza la notación arr[start:stop:step].

import numpy as np

arr = np.array([0, 1, 2, 3, 4, 5])
# Segmentar de índice 1 a 4
print(arr[1:4])  # Output: [1 2 3]

# Segmentar desde el inicio hasta un índice específico
print(arr[:3])  # Output: [0 1 2]

# Segmentar desde un índice específico hasta el final
print(arr[3:])  # Output: [3 4 5]

# Segmentar con un paso específico
print(arr[::2])  # Output: [0 2 4]

Segmentación en arrays multidimensionales

La segmentación puede aplicarse a cada dimensión de arrays multidimensionales.

arr_2d = np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]])

# Segmentar filas y columnas específicas
print(arr_2d[:2, 1:3])  # Output: [[20 30] [50 60]]

# Segmentar una columna específica
print(arr_2d[:, 1])  # Output: [20 50 80]

# Segmentar con pasos en múltiples dimensiones
print(arr_2d[::2, ::2])  # Output: [[10 30] [70 90]]

Segmentación inversa

La segmentación puede utilizar pasos negativos para invertir el orden de los elementos.

# Invertir los elementos de un array unidimensional
print(arr[::-1])  # Output: [5 4 3 2 1 0]

# Invertir las filas y/o columnas de un array multidimensional
print(arr_2d[::-1, ::-1])  # Output: [[90 80 70] [60 50 40] [30 20 10]]

Segmentación y boolean indexing

Los arrays booleanos pueden utilizarse en combinación con la segmentación para seleccionar elementos que cumplan ciertas condiciones.

mask = arr > 2
# Segmentar después de aplicar una máscara booleana
print(arr[mask][1:3])  # Output: [4 5]

Segmentación y fancy indexing

Es posible segmentar los resultados obtenidos mediante fancy indexing.

indices = [0, 2, 4]
# Aplicar segmentación tras fancy indexing
print(arr[indices][1:3])  # Output: [2 4]

Segmentación con Ellipsis y np.newaxis

El uso de ... (Ellipsis) y np.newaxis altera el número de dimensiones del array.

# Utilizar Ellipsis para seleccionar todas las dimensiones restantes
arr_3d = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
print(arr_3d[..., 1])  # Output: [[2 4] [6 8]]

# Utilizar np.newaxis para añadir nuevas dimensiones
print(arr[:, np.newaxis])  # Output: [[0] [1] [2] [3] [4] [5]]

Estas distintas técnicas de segmentación proporcionan una increíble versatilidad y capacidad para manipular y procesar grandes cantidades de datos de forma eficiente en Numpy.

Certifícate en Numpy con CertiDevs PLUS

Ejercicios de esta lección Indexación y segmentación en Numpy

Evalúa tus conocimientos de esta lección Indexación y segmentación en Numpy con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Todas las lecciones de Numpy

Accede a todas las lecciones de Numpy y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Certificados de superación de Numpy

Supera todos los ejercicios de programación del curso de Numpy y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.

En esta lección

Objetivos de aprendizaje de esta lección

  • Comprender la diferencia entre indexación simple y avanzada (fancy indexing, boolean indexing).

  • Aplicar técnicas de segmentación (slicing) para extraer subconjuntos de datos.

  • Manipular arrays multidimensionales usando diferentes métodos de indexación.

  • Utilizar np.newaxis y Ellipsis para alterar dimensiones del array.

  • Combinar diferentes métodos de indexación para operaciones complejas.