Artículos técnicos

Perspectivas de MathWorks

Indexación de matrices en MATLAB


Autores:

  • Steve Eddins, MathWorks
  • Loren Shure, MathWorks

8 minutos de lectura

Resumen

  • La indexación de matrices permite seleccionar y modificar datos de forma eficiente, y constituye la base de la manipulación de arrays y los algoritmos basados en matrices.
  • MATLAB admite múltiples estilos de indexación, como indexación por subíndices y vectores, además del operador de dos puntos y la palabra clave end para acceder a rangos y elementos de contorno.
  • La indexación permite extraer y asignar elementos, lo que facilita transformaciones concisas como reordenar elementos, sustituir valores y operar con subarrays.
  • Una indexación eficaz sustenta la vectorización, lo que reduce la dependencia de bucles y produce código que normalmente es más breve, claro y rápido.

Indexar una matriz permite seleccionar o modificar un subconjunto de sus elementos. MATLAB® ofrece múltiples estilos de indexación que, además de potentes y flexibles, son legibles y expresivos. Las matrices son un componente fundamental de MATLAB para organizar y analizar datos, y la indexación es esencial para manipularlas de forma eficaz y comprensible.

La indexación está estrechamente relacionada con otro término frecuente para la comunidad usuaria de MATLAB: la vectorización. La vectorización consiste en utilizar operaciones de MATLAB con matrices y vectores en lugar de operaciones escalares, lo que suele producir código más breve, más legible y expresivo desde el punto de vista matemático y, en ocasiones, más rápido.

Indexación de vectores

Comencemos con un caso sencillo de un vector y sus subíndices.

 v = [16 5 9 4 2 11 7 14];

El subíndice puede ser un único valor:

 v(3) % Extract the third element
 ans =
 9

El propio subíndice también puede ser otro vector.

 v([1 5 6]) % Extract the first, fifth, and sixth elements
 ans =
 16 2 11

La notación con dos puntos de MATLAB permite extraer fácilmente un rango de elementos de v.

 v(3:7) % Extract the third through the seventh elements
 ans =
 9 4 2 11 7

Intercambie las dos mitades de v para crear un nuevo vector.

 v2 = v([5:8 1:4]) % Extract and swap the halves of v
 v2 =
 2 11 7 14 16 5 9 4

El operador especial end es una forma abreviada y sencilla de hacer referencia al último elemento de v.

 v(end) % Extract the last element
 ans =
 14

El operador end puede utilizarse en un rango.

 v(5:end) % Extract the fifth through the last elements
 ans =
 2 11 7 14

Incluso puede realizar operaciones aritméticas con end.

 v(2:end-1) % Extract the second through the next-to-last elements
 ans =
 5 9 4 2 11 7

Combine el operador de dos puntos y end para lograr diversos efectos, como extraer uno de cada k-ésimo elemento o invertir todo el vector.

 v(1:2:end) % Extract all the odd elements
 ans =
 16 9 2 7
 v(end:-1:1) % Reverse the order of elements
 ans =
 14 7 11 2 4 9 5 16

Una expresión de indexación en el lado izquierdo del signo igual permite sustituir determinados elementos del vector.

 v([2 3 4]) = [10 15 20] % Replace some elements of v
 v =
 16 10 15 20 2 11 7 14

Normalmente, el número de elementos del lado derecho debe coincidir con el número de elementos a los que hace referencia la expresión de indexación del lado izquierdo. No obstante, siempre se puede utilizar un escalar en el lado derecho. Esto se denomina expansión escalar.

 v([2 3]) = 30 % Replace second and third elements by 30
 v =
 16 30 30 20 2 11 7 14

Recuerde: MATLAB utiliza indexación basada en 1. En la indexación de matrices, algunos lenguajes comienzan por cero. Otros lenguajes, como MATLAB, comienzan por 1. MATLAB utiliza la misma notación que suele aparecer en los libros de matemáticas. ¿Por qué MATLAB empieza por 1? Según Cleve Moler, fundador de MATLAB, "así es como se hacen las cosas en matemáticas".

Indexación de matrices con dos subíndices

Veamos ahora la indexación de una matriz. En los ejemplos utilizaremos un cuadrado mágico.

 A = magic(4)
 A =
 16 2 3 13
 5 11 10 8
 9 7 6 12
 4 14 15 1

Lo más habitual es indexar matrices con dos subíndices: el primero para las filas y el segundo para las columnas.

La forma más sencilla selecciona un único elemento.

 A(2,4) % Extract the element in row 2, column 4
 ans =
 8

De forma más general, uno de los subíndices o ambos pueden ser vectores.

 A(2:4,1:2)
 ans =
 5 11
 9 7
 4 14

Un único ":" en la posición de un subíndice es una notación abreviada de 1:end, y con frecuencia se utiliza para seleccionar filas o columnas completas.

 A(3,:) % Extract third row
 ans =
 9 7 6 12
 A(:,end) % Extract last column
 ans =
 13
 8
 12
 1

A veces surgen dudas sobre cómo seleccionar elementos dispersos de una matriz. Por ejemplo, suponga que desea extraer los elementos (2,1), (3,2) y (4,4) de A.

Matriz de 4x4 con tres valores resaltados y dispersos en distintas posiciones de la matriz. Se encuentran, respectivamente, en la fila 2, columna 1; fila 3, columna 2; y fila 4, columna 4.

Elementos dispersos de una matriz.
¿Cómo se puede representar la salida deseada?

La expresión A([2 3 4], [1 2 4]) no produce el resultado deseado. Este diagrama muestra cómo funciona la indexación con dos subíndices.

Para extraer elementos dispersos de una matriz se necesita otro estilo de indexación, que es el tema de la siguiente sección.

Indexación lineal

¿Qué acción realiza la expresión A(14)?

Cuando se indexa la matriz A con un único subíndice, MATLAB trata A como si sus elementos estuvieran dispuestos en un largo vector columna, recorriendo las columnas consecutivamente, como se muestra aquí:

16
5
9
...
8
12
1

Sugerencia: MATLAB utiliza orden por columnas, la indexación lineal comienza recorriendo las columnas consecutivamente.

La expresión A(14) simplemente extrae el elemento número 14 del vector columna implícito. Esta forma de indexar una matriz con un único subíndice suele denominarse indexación lineal.

En el diagrama, que muestra los índices lineales en la esquina superior izquierda de cada elemento de la matriz, puede observar que A(14) equivale a A(2,4).

El único subíndice puede ser un vector que contenga más de un índice lineal, como en este ejemplo:

 A([6 12 15])
 ans =
 11 15 12

Volvamos al problema de extraer únicamente los elementos (2,1), (3,2) y (4,4) de A. Puede utilizar indexación lineal para lograrlo.

 A([2 7 16])
 ans =
 5 7 1

En este ejemplo resulta fácil verlo, pero ¿cómo puede calcular los índices lineales en general? MATLAB ofrece una función denominada sub2ind que convierte subíndices de fila y columna en índices lineales. Puede utilizarla para extraer los elementos deseados de este modo:

 idx = sub2ind(size(A), [2 3 4], [1 2 4])
 ans =
 2 7 16
 A(idx)
 ans =
 5 7 1

Indexación lógica

Otra variante, la indexación lógica, es una notación concisa y expresiva útil en múltiples aplicaciones, como el procesamiento de imágenes. En la indexación lógica, se utiliza un único array lógico como subíndice de la matriz.

Este es un ejemplo de array lógico que podría utilizar:

A > 12 

ans =
4×4 logical array

1  0  0  1
0  0  0  0
0  0  0  0
0  1  1  0

Estas son las posiciones de la matriz donde la expresión lógica es verdadera; en este caso, cualquier posición cuyo valor sea superior a 12.

La expresión A(A > 12) extrae los elementos de la matriz correspondientes a los valores distintos de cero del array lógico. La salida siempre tiene forma de vector columna.

A(A > 12) 

ans =

 16
 14
 15
 13

Muchas funciones de MATLAB que comienzan por is devuelven arrays lógicos y resultan muy útiles para la indexación lógica. Por ejemplo, puede sustituir todos los elementos NaN de un array por otro valor utilizando una combinación de isnan, indexación lógica y expansión escalar en una sola línea de código.

 B(isnan(B)) = 0

MATLAB dispone de múltiples funciones de arrays de cadenas que devuelven arrays lógicos, como contains, startsWith y matches. Puede utilizarlas para operar con texto sirviéndose de indexación lógica. Por ejemplo, puede extraer todos los nombres de programas espaciales que contengan "Skylab".

>> names

names =

  6×1 string array

    "Mercury"
    "Gemini"
    "Apollo"
    "Skylab"
    "Skylab B"
    "ISS"

>> names(contains(names,"Skylab"))

ans =

  2×1 string array

    "Skylab"
    "Skylab B"

La indexación lógica está estrechamente relacionada con la función find. La expresión A(A > 5) equivale a A(find(A > 5)). La expresión de indexación lógica es más rápida en casos sencillos, pero puede utilizar find si necesita los valores de índice para otra operación del cálculo. Por ejemplo, suponga que desea sustituir temporalmente los valores NaN por ceros, realizar un cálculo y luego volver a colocar los valores NaN en sus posiciones originales. En este ejemplo, el cálculo consiste en un filtrado bidimensional empleando filter2. Puede hacerlo de este modo:

 nan_locations = find(isnan(A)); 

 A(nan_locations) = 0; 

 A = filter2(ones(3,3), A); 

 A(nan_locations) = NaN; 

Esperamos que los ejemplos de este artículo sirvan para mostrar algunas formas en que puede expresar algoritmos de manera compacta y eficiente. Incorporar estas técnicas y las funciones relacionadas a su repertorio de programación en MATLAB amplía su capacidad de crear código conciso, legible y vectorizado.

Publicado en 2024


Productos utilizados: MATLAB

Siga explorando