Matlab - Función Find y grillado de datos

 
Vista:
sin imagen de perfil
Val: 11
Ha disminuido su posición en 2 puestos en Matlab (en relación al último mes)
Gráfica de Matlab

Función Find y grillado de datos

Publicado por Daiana (4 intervenciones) el 10/10/2019 20:11:45
Buenos días a todos!

Tengo una gran duda respecto a como funciona la función FIND en Matlab.

Estaba haciendo un programa que entre otras cosas utilizaba esta función y me dio varios problemas.
Un poco resumido lo que estaba haciendo era lo siguiente:
Mi base de datos es un archivo .mat en donde se guarda información sobre rayos meteorológicos (o lightning). Esa información consiste en el tiempo, la ubicación (en latitud y longitud), error de precisión, energía, entre otros para cada rayo.

Para este caso solo estaba utilizando la ubicación, osea los valores de latitud y longitud en grados decimales. Un ejemplo de estos valores sería:
Latitud: Longitud:
-24,3630000000000 -62,5710000000000
-23,3254000000000 -62,4138000000000
32,9734000000000 48,2879000000000
-24,6303000000000 -62,8270000000000
-23,3717000000000 -62,5272000000000

Cada par, (Lat,Lon) sería un rayo. Tengo un archivo .mat para cada día de un año (osea 365/364 archivos por año). Lo que estoy haciendo es contar la cantidad de rayos que tengo por cada año, pero en una grilla determinada. Por ejemplo, cuantos rayos caen en un año en una grilla de 0.2° x 0.2° (lat,lon).

Lo que hago entonces es, para un año determinado, abrir cada archivo .mat (mediante el uso de un ciclo for), extraer de ahi los rayos que se encuentren en mi área de interés (por ejemplo toda Argentina), y de ahí para cada día busco los rayos (lat, lon) que se encuentran cerca de un nodo de mi grilla (previamente armada) y sumo todos los rayos que cumplen con esa condición. Entonces para esa posición del nodo de la grilla le asigno el valor de todos los rayos que estaban a la distancia asignada. Después sumo todos los días y obtengo el total anual.

El primer código que utilice para hacer la parte de buscar los rayos cerca de los nodos fue esta:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
red=[latitud longitud]; % latitud y longitud de los rayos
% Grilla:
LO=[lon_oeste:celda:lon_este];  % Celda es el ancho de la celda de la grilla (0.2 en este caso)
LA=[lat_norte:-celda:lat_sur];
[lo,la]=meshgrid(LO,LA);
[dlat,dlon]=size(lo);
At=ones(length(lat),1);
An=ones(length(lon),1);
 
for k=1:dlat
     for l=1:dlon
          dif_lat=0;
          dif_lon=0;
          dif_lat=abs(red(:,1)-At.*la(k,l));
          dif_lon=abs(red(:,2)-An.*lo(k,l));
          [a,b]=find(dif_lat<=(celda/2) & dif_lon<=(celda/2));
          ray(k,l)=sum(b);
      end
end
 
Rr(:,:,j)=ray;
R=Rr>=1;
 
% Suma de todos los datos
SRr=sum(Rr,3);

El problema fue que del total de rayos (874 9528) antes de pasar por la grilla, una vez que pasaba por el FOR me quedaban menos (874 6138), poco mas de 3 mil rayos menos. Yo se que el código con los menores e iguales debería estar contándome de mas, porque estoy considerando los limites como parte de nodos cercanos. Por eso me pareció raro.

Cambie varias cosas y seguí con el mismo problema. Entonces se me dio por probar si era algún tema de puntos flotantes (lo cual no termino de entender al 100%) y pase todos los valores con los que trabajo a enteros.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
At=int16(ones(length(lat),1));
lat_f=int16(100.*lat);
la_f=int16(100.*la);
lon_f=int16(100.*lon);
lo_f=int16(100.*lo);
lim=int16((celda*100)/2);         % valor limite que considero cercano al nodo (la mitad de la celda de la grilla)
 
for k=1:dlat
     for l=1:dlon
          dif_lat=[];
         dif_lon=[];
         An=[];
         dif_lat=(lat_f-At.*la_f(k,l));
         a=find(dif_lat<=lim & dif_lat>-lim);
         An=int16(ones(length(lon_f(a)),1));
         dif_lon=(lon_f(a)-(An.*lo_f(k,l)));
         b=find(dif_lon<=lim & dif_lon>-lim );
         ray(k,l)=length(b);
         b=[];
     end
end

Cambié un poco lo de adentro del doble FOR para evitar que cuente dos veces un valor. Cuestión que de esta forma me toma el total de rayos bien. Pero no me parece una forma correcta de hacerlo, cada vez que paso a entero la latitud y longitud estoy perdiendo información (en este caso estaría tomado dos decimales como significativos por eso multiplico por 100, podría tomar mas y usar un int32?).

Bueno, espero me haya podido explicar bien. No puedo subir todo el script lamentablemente, y la base de datos tampoco.

Desde ya muchas gracias! Cualquier información al respecto es bienvenida!

Saludos!
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de JOSE JEREMIAS CABALLERO
Val: 8.145
Oro
Ha mantenido su posición en Matlab (en relación al último mes)
Gráfica de Matlab

Función Find y grillado de datos

Publicado por JOSE JEREMIAS CABALLERO (5621 intervenciones) el 10/10/2019 23:28:04
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Uso de la funcion find.
>> A=[3 4 5 7 15 6   78]
 
A =
 
     3     4     5     7    15     6    78
 
>> [a, b]=find(A==7)
 
a =
 
     1
 
 
b =
 
     4
 
>> % en la variable a se guarda la fila donde encuentra el valor de 7
>> % en la variable b se guarda la columna donde se encuentra el valor e 7


1
b=find(dif_lon<=lim & dif_lon>-lim );
en términos generales que es lo deberia hacer según su punto de vista este sentencia.

Saludos
JOSE JEREMIAS CABALLERO
Asesor de Proyectos con Matlab
Servicios de programación matlab
Servicio de Asesoría Online en Matlab


http://matlabcaballero.blogspot.com
https://www.facebook.com/matlabcaballero
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 11
Ha disminuido su posición en 2 puestos en Matlab (en relación al último mes)
Gráfica de Matlab

Función Find y grillado de datos

Publicado por Daiana (4 intervenciones) el 10/10/2019 23:49:42
Hola! Primero que nada, gracias por responder!

1
[a, b]=find(A==7)

Esto mas o menos lo entiendo, igualmente cuando no trabajo con valores enteros, no puedo usar el '==' porque se saltea muchos valores (por algo de problemas de redondeo en los numeros float creo).

En mi código
1
[a,b]=find(dif_lat<=(celda/2) & dif_lon<=(celda/2));


cuando la uso, mi A sería dif_lat y/o dif_lon. Que son vectores columna, entonces en la variable b guardo los valores 1 (solo hay una columna) donde hay datos que cumplan la condicion dentro del find, cada uno de esos datos es un rayo. Yo los sumo y asigno ese valor al nodo de la grilla mas cercano. Está asi, pero seria lo mismo tomar la longitud del vector 'a' también (Hay partes del código que no las hice yo).

Esta sentencia
1
b=find(dif_lon<=lim & dif_lon>-lim );

lo que hace es tomar las diferencias, entre la ubicación en longitud del rayo y la longitud de un nodo de la grilla específico (este va cambiando dentro del for) y quedarse solo con los rayos que estén a una distancia (positiva o negativa) menor a 'lim'.
Cabe aclarar que previamente hice lo mismo con la latitud y pase a filtrar los datos por longitud que ya cumplian la condición anterior.

1
a=find(dif_lat<=lim & dif_lat>-lim);
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 939
Bronce
Ha mantenido su posición en Matlab (en relación al último mes)
Gráfica de Matlab

Función Find y grillado de datos

Publicado por Daniel (281 intervenciones) el 11/10/2019 09:58:54
Hola,

Si lo único que haces es contar ocurrencias no necesitas find, simplemente puedes sumar los valores lógicos (true es 1 y false es 0). Además, es más es una solución bastante más rápida.

Así el numero de rayos en una celda se puede obtener con algo como

1
sum(dif_lat<=(celda/2) & dif_lon<=(celda/2));

Saludos,
Daniel Rodríguez.
Analytics Lane
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 11
Ha disminuido su posición en 2 puestos en Matlab (en relación al último mes)
Gráfica de Matlab

Función Find y grillado de datos

Publicado por Daiana (4 intervenciones) el 11/10/2019 17:42:57
Hola!!

Gracias! Me ahorraria unas cuantas líneas.
Lo voy a implementar, crees que de esa forma ya puedo trabajar con nùmeros decimales sin problema?

Saludos!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 939
Bronce
Ha mantenido su posición en Matlab (en relación al último mes)
Gráfica de Matlab

Función Find y grillado de datos

Publicado por Daniel (281 intervenciones) el 12/10/2019 15:41:04
No deberías tener ningún problema a la hora de usar decimales ya que miras si los valores son inferiores a un umbral.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar