Cómo acceder a los valores de estas variables MATLAB en base a una matriz que almacena los índices de las columnas requeridas

La descripción de su problema es que tiene un tipo de datos jerárquico complejo (matriz de clase de estructura de matlab) y necesita extraer datos de él de acuerdo con algunas reglas mientras usa claves codificadas en su matriz M

Hay dos partes en su problema . El primero es el manejo automatizado de la matriz M (extracción de valores de índice de M ) mientras se siguen las reglas de clase y tipo junto con las reglas codificadas en M. El segundo es la extracción de datos de las matrices S1, S2, S3 y S4 de origen utilizando un enfoque conveniente para el análisis / manipulación eficiente.

Describo dos enfoques para implementar la primera parte del manejo automatizado de M aquí. Primero uso un enfoque de contabilidad oficial estándar. Luego muestro una alternativa más elegante basada en la conversión de la matriz M en una imagen, luego analizándola. El enfoque de análisis basado en imágenes es más eficiente e intuitivo.

(Su matriz M se transcribió de la imagen en esta página usando OCR, por lo que podría no coincidir con su matriz real).

  Ms =
 [4x2] [4x2] [4x2] [3x2] [3x2] [3x2] |  (datos de S1)
 - + ----- + ---- + --------- + ----- + ----- + --- |
 [7x2] [7x2] [7x2] [7x2] [7x2] [7x2] |  (datos de S2)
 - + ----- + ---- + --------- + ----- + ----- + --- |
 [4x2] [4x2] [4x2] [3x2] [3x2] [3x2] |  (datos de S3)
 - + ----- + ---- + --------- + ----- + ----- + --- |
 [7x2] [7x2] [7x2] [7x2] [7x2] [7x2] |  (datos de S4)
 - = ----- = ----- = -------- = ----- = ----- = --- |
  dat1 dat2 dat3 dat4 dat5 dat6 |
 --------------------------------------- |

Según su descripción, tiene cuatro fuentes de datos y seis interpretaciones de los datos obtenidos al mezclar los datos de las fuentes de acuerdo con las reglas de uso. Las reglas indiciales se dan en la matriz M Mi primer paso es convertir M en submatrices que simplifican la descripción. Interpreto mis submatrices como se muestra arriba.

Entonces necesito reducir M en 24 submatrices. Una descripción de una submatriz en una matriz más grande requiere cuatro números / valores / puntos: una ubicación de referencia, un ancho y un valor de altura. Por ejemplo, podemos suponer que estos cuatro puntos describen la esquina superior izquierda (r0, c0) y la esquina inferior derecha (r1, c1) de cada submatriz. Estos puntos se definen con respecto a la esquina superior izquierda de M (la posición (1,1) ).

Esto permite que la matriz de submatrices 4 × 6 se describa mediante 4 conjuntos de matrices 4 × 6 llamadas r0 , c0 , r1 y c1 , y nos brinda un enfoque sistemático para recopilar valores de índice de la matriz M

Enfoque de contabilidad estándar

c0 y c1 son fáciles de calcular (AP). Para calcular r0 creo dos matrices, una llamada nlines , la otra la matriz de shift . La matriz nlines almacena el número de filas (4,7,4,7) para Data1 / 2 y (3,7,3,7) para Data3 / 4. La matriz de desplazamiento almacena los desplazamientos introducidos por NaN (puede ver aquí que trato a mis matrices como imágenes y elementos como píxeles). Conocemos los valores iniciales de r0 (r0(1,:)=ones(1,6)) y los valores finales de r1 ( r1(4,:)=25*ones(1) ). Entonces tenemos que bajar para calcular r0 , y subir desde abajo para calcular r1 . Este enfoque se entiende mejor leyendo el código.

Interpretación de M como una imagen (requiere la caja de herramientas de procesamiento de imágenes de matlab)

M es una matriz de 25 × 12 y nuestro objetivo es descubrir r0, c0, r1, c1 de manera eficiente.

Los valores de NaN en M representan marcadores que segregan cuatro regiones en la matriz. La siguiente imagen en escala de grises muestra una M. normalizada. Podemos convertirla en una matriz lógica donde cada elemento es el resultado lógico de ~ isnan. Esta matriz binaria se muestra a continuación. La imagen binaria muestra que los ‘componentes’ que no están ‘conectados’ (las manchas blancas que no se tocan ni tienen píxeles adyacentes), cada uno representa 6 submatrices de M.

Así que hago un análisis de componentes conectados y descubro qué grupos de píxeles están asociados con cuál de los cuatro blobs. Los grupos de píxeles individuales se muestran resaltados por un color diferente en la imagen titulada ‘componente conectado de BW’.

Como ya sabemos que una submatriz solo puede tener 2 columnas, podemos dividir / segmentar estos blobs en grupos de 6. Esto se muestra a continuación, imagen a la derecha. La imagen tiene 24 cuadros de colores que representan nuestras submatrices. También conocemos todos los píxeles que pertenecen a cada una de estas submatrices. Entonces r0, r1, c0 y c1 son la menor fila, la fila más alta, la columna menos y el índice de columna más alto en cada uno de los 24 grupos. Ese es el segundo enfoque para determinar las submatrices.

Entonces, una vez que determinamos el conjunto de cuatro puntos, debemos buscar los valores de índice almacenados en M y almacenarlos en algún lugar. Creo una matriz de celdas de tamaño 4 × 6 llamada BigS (para Big Store) y almaceno todos los índices de cada una de las 24 submatrices allí. BigS (i, j) le permite clasificar o utilizar fácilmente cualquier conjunto de datos que necesite.

Ahora no sé qué análisis le interesan. Todos los métodos para obtener datos de Si pueden provocar la pérdida de información. Pero voy a suponer que sabes lo que estás haciendo, y utilizaré un enfoque ingenuo en el que descarto toda la información sobre las 18 estructuras originales durante la recuperación.

En el siguiente código, creo un prototipo de los arrays de estructura, S1 .. S4. El contenido de las matrices se muestra en la ventana de comandos.

Versión 2.a – Enfoque de contabilidad

  función [Datos1, Datos2, Datos3, Datos4, Datos5, Datos6] = basura
 %% Teneduría de libros
 cierra todo;  limpiar todo;  clc
 % Leer el archivo de imagen;  FUNCION LOCAL  No disponible en su instalación de Matlab
 % p = xsnap (1);  % Tomar instantánea de escritorio
 % M = xread (p);  % Leer texto usando Tesseract

 % Definir M. Puede haber ruido relacionado con OCR en los números transcritos
 M = uint16 ([960 1340 3040 3500 4990 5580 6950 7555 8850 9355 11025 11480; 13010 13440 15000 15535 17055 17640 18970 19625 21020 21590 23035 23520; 25050 25425 27035 27550 28990 29575 31055 31630 33010 33570 35010 35405; 37060 374565 39020 3970 35010 35405; 37060 374565 43020 NaN NaN NaN NaN NaN NaN; NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN; 1010 1470 2060 2535 3045 3620 4045 4600 5035 5550 5990 6460;
     7085 7570 8010 8500 9085 9640 10055 10595 11020 11580 12010 12510; 13080 13535 14030 14590 15065 15625 16040 16595 17045 17575 18025 18490; 19065 19450 20065 20520 21000 21540 22005 22570 23030 23555 23995 24465;  25080 25565 26060 26565 27105 27680 28025 28565 29030 29540 29975 30415; 30995 31365 31985 32480 33015 33550 33980 34555 34980 35465 35940 36465; 37020 37430 38020 38475 38990 39495 40005 40470 40955 41455 41920 42305;
     NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN; 955 1475 3010 3565 5045 5555 7030 7560 8980 9610 10945 11525; 13100 13780 14990 15435 16965 17535 18990 19520 20995 21545 22985 23535;  25035 25570 27010 27530 28985 29455 30955 31435 32995 33550 35005 35605; 37050 37685 38985 39550 40995 41540 NaN NaN NaN NaN NaN NaN NaN; NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN;
     935 1375 1980 2495 3005 3580 3960 4595 5045 5545 5980 6405; 6940 7335 7960 8405 8970 9485 9970 10570 11025 11520 11950 12400; 12985 13430 13895 14385 14835 15405 15855 16445 16870 17415 17930 18350;  13%. 42380]);

 %% Genera un prototipo para S1, S2, S3, S4
 % Si es una matriz de 18 estructuras.
 % Cada estructura en Si tiene 13 campos en total.  13 = Mi elección al azar.
 % Cada estructura en Si tiene 'val' como el 13er campo.
 % Si.val tiene 18 matrices 3xN (apunta a todos los '.val's en Si)
 % Todos los campos excepto 'val' tienen matrices lógicas aleatorias que los completan
 % (puede estar vacío)
 % Utilizo N = 42380 ya que max (M (:)) = 42380;  Yo uso valores lógicos para datos desde
 % usa 8 bits, y el doble usa 8 bytes (64b), que multiplicado por 18 veces N es un
 % bocado  Si N es una variable, entonces la matriz M controla qué índices de
 % S1 {i} .val (:, x: y) que solicita (ya que x: y se origina en M).  Entonces serás
 % bien con lo que tengas Ni.
 [S1, S2, S3, S4] = makeUpRandomCrap (42380, verdadero); 

 %% IMPLEMENTACIÓN
 % NLINES MATRIX, describe el número de filas que cada submatriz de Ms describe
 % También se puede ver como el proxy principal para la Sra. Me verá usar esto
 % a lo largo para indicar los límites de conteo.
 n = [4 4 4 3 3 3;  7 * unos (1,6);  4 4 4 3 3 3;  7 * unos (1,6)];
 numCol = 2;  % Número de columnas en cada submatriz

 % SHIFT MATRIX, para tener en cuenta el grosor / ancho de línea variable de las líneas NaN
 % Hay efectivamente tres líneas que separan M horizontalmente.  Estos molestos
 El porcentaje de líneas varía en grosor, lo que causa dolor al contar las estrategias.
 s = [1 1 1 2 2 2;  1 1 1 1 1 1;  1 1 1 2 2 2;  1 1 1 1 1 1];

 % Coordenadas de la esquina superior izquierda de cada submatriz = (r0, c0) [par ordenado]
 c0 = ones (tamaño (n, 1), 1) * [1: numCol: tamaño (M, 2) -1];  % omitir cols por numcols
 r0 (1,:) = ones (tamaño (n (1, :)));  Matriz% Orígenes, define la primera fila
 para i = 2: tamaño (n, 1),% comienza en la segunda fila ya que la primera ya está definida
     r0 (i,:) = r0 (i-1,:) + n (i-1,:) + s (i-1, :);  % X coordenada de las esquinas superiores izquierdas de cada submatriz
 fin;

 % Coordenadas de la esquina inferior derecha de cada submatriz = (r1, c1) [par ordenado]
 c1 = ones (tamaño (n, 1), 1) * [(1 + numCol-1): numCol: tamaño (M, 2)];  % Saltar cols por numcols-1
 r1 = ceros (tamaño (n));  % Dado que volvemos de la última fila a la primera, necesitamos y1 mat defind
 r1 (final,:) = tamaño (M, 1) * unos (tamaño (n (1, :)));  % Definir la última fila
 para i = (tamaño (n, 1) -1): - 1: 1% Retrocede desde la última fila pero una fila, ya que la fila lar ya está definida
     r1 (i,:) = r1 (i + 1,:) - n (i + 1,:) - s (i, :);
 fin

 para i = 1: tamaño (n, 1),% Ciclo a través de Si
     para j = 1: tamaño (n, 2)% Ciclo a través de datos j
         indexS = [];  % Crear almacén de índice temporal
         para k = 1: n (i, j)% Paso a través de las filas en M
             indexS = [indexS [M (r0 (i, j) + k-1, c0 (i, j)) :( 1): M (r0 (i, j) + k-1, c1 (i, j)) ]];  % Recopilar índices, agregar conjunto (Set-Union)
         fin
         BigS (i, j) = {indexS};  % Almacene el conjunto final adjunto en BigS.  Dataj está hecho de Si con i = 1: 4, Si contribuye Dataj con j = 1: 6
     fin;
 fin;

 %% OBTENER DATOS
 % Ahora no sé qué análisis le interesan. Todos los métodos para
 El% de recuperación de datos de Si puede provocar la pérdida de información.  Pero voy a
 % asumo que sabes lo que estás haciendo y utilizas un enfoque ingenuo donde yo
 % descarta toda la información sobre las 18 estructuras originales durante
 % de recuperación.

 % La plantilla para extraer datos es Si (k) .val (:, BigS {i, j})

 para i = 1: 4,
     para j = 1: 6,
         para k = 1:18,
             % Almacenar en matrices numéricas individuales, un cuboide 3xNx18 llamado
             % DatajSi, donde j = 1: 6 e i = 1: 4.  Estos representan bloques de jth
             % de datos aportados por ith Si.
             eval (['' Datos 'num2str (j)' S 'num2str (i)' (:,:, k) = S 'num2str (i)' ('num2str (k)') .val (:, BigS {'num2str (i) ',' num2str (j) '});']);
         fin
     fin
 fin
 %% DatajSi son las siguientes definiciones son TODAS simples mxArrays
 % que ocupa menos espacio que cell / struct.  cell / structs también conducen a memfrag
 % y en general mem (struct) >> mem (cell)> matrices simples.  A menos que haya mezclado
 % tipos, no hay una buena razón para usar estructuras.

 % Aquí hay una manera fácil de almacenar cosas.
 Datos1 = [Datos1S1 Datos1S2 Datos1S3 Datos1S4];  % tamaño (Datos1) = [3 9982 18]
 Datos2 = [Datos2S1 Datos2S2 Datos2S3 Datos2S4];  % tamaño (Datos2) = [3 10005 18]
 Datos3 = [Datos3S1 Datos3S2 Datos3S3 Datos3S4];  % tamaño (Data3) = [3 12327 18]
 Datos4 = [Datos4S1 Datos4S2 Datos4S3 Datos4S4];  % tamaño (Datos4) = [3 11315 18]
 Datos5 = [Datos5S1 Datos5S2 Datos5S3 Datos5S4];  % tamaño (Datos5) = [3 10695 18]
 Datos6 = [Datos6S1 Datos6S2 Datos6S3 Datos6S4];  % tamaño (Datos6) = [3 9460 18]

 % Si desea que todos los Dataj sean una matriz 3XN, perder toda la información de estructura
 Datos1 = remodelar (Datos1, tamaño (Datos1,1), tamaño (Datos1,2) * tamaño (Datos1,3));  % tamaño (Datos1) = [3 179676];
 Datos2 = remodelar (Datos2, tamaño (Datos2,1), tamaño (Datos2,2) * tamaño (Datos2,3));  % tamaño (Datos2) = [3 180090];
 Data3 = remodelar (Data3, tamaño (Data3,1), tamaño (Data3,2) * tamaño (Data3,3));  % tamaño (Data3) = [3 221886];
 Data4 = remodelar (Data4, tamaño (Data4,1), tamaño (Data4,2) * tamaño (Data4,3));  % tamaño (Datos4) = [3 203670];
 Data5 = remodelar (Data5, tamaño (Data5,1), tamaño (Data5,2) * tamaño (Data5,3));  % tamaño (Data5) = [3 192510];
 Data6 = remodelar (Data6, tamaño (Data6,1), tamaño (Data6,2) * tamaño (Data6,3));  % tamaño (Datos6) = [3 170280];
 fin

 %% No te preocupes por el resto de este script.  Solo basura usada para la demostración.
 función U = setUnionNoRep (a, b, c, d)% <- No se utiliza.  El uso depende de cómo desee recopilar conjuntos y comportamientos para evocar
 U = unión (a, unión (b, unión (c, d)));
 fin

 función U = setUnion (a, b, c, d)% <- No se utiliza.  El uso depende de cómo desee recopilar conjuntos, etc.
 U = [abcd];
 fin

 función A = xrandMod
 a = 0.5;  b = 29.499999999999;  A = a + (ba) * rand (1,70);  A = redondo (A);
 fin

 función [S1, S2, S3, S4] = makeUpRandomCrap (N, showPrintOut)
 rng (4)% Siembra el RNG para evitar fluctuaciones
 S1 = [];  S2 = [];  S3 = [];  S4 = [];  flds = [{'' Elon '}, {' Musk '}, {' dice '}, {' él '}, {' perdido '}, {' a '}, {' multi '}, {' billón '} , {'dollar'}, {'contract'}, {'when'}, {'SpaceX'}, {'didnt'}, {'hire'}, {'the'}, {'public'}, { 'oficial'}];% # ok 
 structNoms = [{'Crédito'}, {'calificaciones'}, {'agencias'}, {'solo'}, {'realizado'}, {'eso'}, {'clima'}, {'cambio'} , {'amenaza'}, {'a'}, {'mundo'}, {'economía'} flds];  basura = único (xrandMod);
 para i = 1: 17, para j = 1: 12, eval ([structNoms {junk (i)} '.' flds {j} '= lógico (rand (round (10 * rand)));']);  fin;  eval (['S1 = [S1' structNoms {basura (i)} '];']);  fin;
 S2 = S1;  S3 = S1;  S4 = S1;  para i = 1: 18, S1 (i) .val = lógico (randn (3, N));  S2 (i) .val = lógico (randn (3, N));  S3 (i) .val = lógico (randn (3, N));  S4 (i) .val = lógico (randn (3, N));  fin
 %% Imprima esto en la ventana com para mostrar cómo se ven las partes internas de S1
 %% Modificar vars llamados JUNKI, JUNKJ manualmente para ver otros campos, etc.
 % junki muestra valores de S1 (i), junkj muestra valores de S1.jthFieldName
 % 1 <= junki <= 18, 1 <= junkj <= 12.  S1.val es el 13er campo.
 si showPrintOut
 junki = ceil (18 * rand);  junkj = ceil (12 * rand);
 fprintf ('\ t \ t \ t \ t% s \ n \ n', 'Así es como se ve S1 -');  disp (S1), fprintf ('\ n \ t \ t \ t \ t% s \ n', ['Esto es lo que parece S1 (' num2str (junki) ') -']);  S1 (junki),% # ok 
 fprintf ('\ n \ t \ t \ t \ t% s \ n', ['Aquí' es lo que parece '' S1. 'flds {junkj}' '', donde '' 'flds {junkj}' '' es un campo - ']);  para i = 1: 17, disp (['S1 (' num2str (i) ').' flds {junkj}]);  eval (['disp (S1 (' num2str (i) ').' flds {junkj} '),']), end;
 fin
 fin
 %%% Gráfico que muestra cómo se superponen los índices D1Si
 %%% Dataj está hecho de unión (resampled_j (Si)) _i = 1: 4.  Aquí resampled_j
 %%% representa la máscara de muestreo jth en Si.  Entonces necesito comparar los seis
 %%% conjuntos de 4 máscaras de remuestreo.
 % % Figura 1)
 %% mar = '+. od';
 %% col = 'rgbkcm';
 %% para i = 1: 6, subtrama (2,3, i),
 %% para j = 1: 4, gráfico (BigS {j, i} / 1e4, [col (i) mar (j) '-'], 'MarkerSize', 2, 'LineWidth', 1.5), espera,
 % % fin;
 %% title (['Cuatro conjuntos de índices cuya unión crea datos' num2str (i)], 'FontSize', 14),
 %% ylabel (['S / 10000'], 'FontSize', 14),
 %% leyenda ('S1', 'S2', 'S3', 'S4', 'ubicación', 'Sureste');
 %% eje ([0 4140 0 4.1])
 % % fin;
 %%
 %%% Gráfico que muestra cómo se superponen los índices DjS1
 %%% Si es muestreado por BigS {i, j} 6 veces para crear componentes para
 %%% Dataj.  Es útil para ver la aparición de los 6 vectores de muestreo.
 % % Figura 1)
 %% mar = '+. ods ^';
 %% col = 'rgbkcm';
 %% para i = 1: 4, subtrama (2,2, i),
 %% para j = 1: 6, gráfico (BigS {i, j} / 1e4, [col (i) mar (j) '-'], 'MarkerSize', 2, 'LineWidth', 1.5), espera,
 % % fin;
 %% title (['Cuatro conjuntos de índices cuya unión crea datos' num2str (i)], 'FontSize', 14),
 %% ylabel (['S / 10000'], 'FontSize', 14),
 %% leyenda ('S1', 'S2', 'S3', 'S4', 'ubicación', 'Sureste');
 %% eje ([0 4140 0 4.1])
 % % fin; 

Versión 2.b: enfoque basado en imágenes

Inserte el valor de M en lo siguiente antes de ejecutar. Requiere la herramienta de procesamiento de imágenes de Matlab (específicamente la función bwlabel). Los números de línea 2-13 en el siguiente reemplazo reemplazan las líneas 28-53 en el script anterior.

  cierra todo;  limpiar todo;  clc
 BW = ~ isnan (M);  % De umbral N, imagen BW
 G = bwlabel (BW);  % Esto podría escribirse manualmente, si no tiene la herramienta de imagen
 A = G;
 intente para i = 1: 6, A (:, 2 * i-1: 2 * i) = A (:, 2 * i-1: 2 * i) * (i + 20) * 100;  fin;  afirmar (longitud (único (A (:))) == 25);
 captura, para i = 1: 6, A (:, 2 * i-1: 2 * i) = A (:, 2 * i-1: 2 * i) * (i + 20 * rand) * 100;  fin;  fin
 r0 = ceros (1,24);  r1 = r0;  c0 = r0;  c1 = r0;
 v = único (A (:));  v = v (2: final);
 para i = 1: 24,
     [Iv, Jv] = ind2sub (tamaño (A), encontrar (A == v (i)));
     r0 (i) = min (Iv);  c0 (i) = min (Jv);
     r1 (i) = max (Iv);  c1 (i) = max (Jv);
 fin; 

Esta es la salida que debería ver cuando ejecuta la función basura.

  %% SALIDA EN LA VENTANA DE MANDO DESCRIBIENDO LOS ARREGLOS Struct S1 / S2 / S3 / S4 MADE UP.
                 Así es como se ve S1:

 1x18 estructura array con campos:
     Elon
     Almizcle
     dice
     él
     perdido
     una
     multi
     mil millones
     dólar
     contrato
     cuando
     SpaceX
     val

                 Así es como se ve S1 (17):
 ans = 
         Elon: [4x4 lógico]
         Almizcle: 1
         dice: 1
           él: [3x3 lógico]
         perdido: 1
            a: [8x8 lógico]
        multi: [9x9 lógico]
      mil millones: 1
       dólar: [6x6 lógico]
     contrato: [2x2 lógico]
         cuando: [9x9 lógico]
       SpaceX: [7x7 lógico]
          val: [3x42380 lógico]

                 Así es como se ve 'S1.Musk', donde 'Musk' es un campo:
 S1 (1) .Musk
      1 1 1 1 1
      1 1 1 1 1
      1 1 1 1 1
      1 1 1 1 1
      1 1 1 1 1
 S1 (2). Anochecer
      1 1 1
      1 1 1
      1 1 1

 ... etc. 

También necesita visualizar las reglas contenidas en la matriz M. Hay dos formas de interpretar todas las reglas M para obtener datos de S: las filas de M codifican las reglas de remuestreo para cada fuente de datos S. Las columnas de M codifican los componentes de S que componen cada dato. La visualización ayuda a comprender la superposición o exclusividad en los índices de muestreo (reglas).

Hay dos guiones de trama al final de mi guión principal. Uno genera la imagen de la fila, el otro genera la imagen de la columna. La imagen a continuación muestra la imagen de la columna. Un par de cosas que veo en la imagen: dos tendencias distintas en los 4 conjuntos de líneas (que representan 4 filas) por subtrama. La tendencia se origina porque el ancho de NaN reduce el número en S3j / S4j en comparación con S1j / S2j.

Hay algunas estructuras de histéresis agradables en Data3-Data6 (por ejemplo, el diagrama de Data6 muestra 5 cuadros, esa es mi estructura de histéresis). Dependiendo de los datos experimentales reales (estocástico / periódico / periódico + no estacionario), es posible que vea de 5 a 4 grupos de subpoblaciones.