To delete rows from a cell array specifying conditions

1 visualización (últimos 30 días)
Yuliia
Yuliia el 17 de Jul. de 2014
Editada: Andrei Bobrov el 17 de Jul. de 2014
I was searching for smth like this, but I haven't found it. The task is: I have a cell array with 25 columns. I need to filter data according to some conditions - only with FLAGS 'O PGD', with SoT 'track' and without 'nan'. So, as a result I need to delete rows which contain this info and corresponding lat, long, so that only reliable data left.
I've written a part of the program to filter data:
A=raw(:,3); %PGD flags
B=raw(:,17); %track,search,memory modes
D=raw(:,14); %distance
C=find(strcmp(' O PGD ',raw(:,3))); %indeces
C1=D(C); %values of distance
E=find(strcmp('track',B)); %indeces
E1=D(E); %values of distance
But, in this case, only distance is filtered and I can't delete another rows(lat,long).
Also, I was trying to work with num data (I mean, to represent the same information, but in num format). I've deleted only rows with 'nan', but in the whole file:
TF1=isnan(num2(:,14)); %condition, build in function
num2(TF1,:)=[]; %delete rows which specify condition in file num2
So, the question will be: how can I delete rows in cell format specifying these conditions OR how to write a condition in num format to delete these rows?
Example of information:
'Flags' 'Dist[km]' 'SoT' 'Lat.' 'Long.'
' O PGD ' 'nan' 'search' 47.562701 2.169937
' O PGD ' 'nan' 'search' 47.562661 2.170009
' O PGD ' 'nan' 'track' 47.562622 2.170081
' O PGD ' 66.4 'track' 47.562584 2.170151
' O PGD ' 66.4 'track' 47.562544 2.170225
' O PGD ' 66.4 'track' 47.562505 2.170297
' O PGD ' 'nan' 'track' 47.562472 2.17038
' O PGD ' 66.3 'track' 47.562433 2.170453
' O PGD ' 66.3 'track' 47.562395 2.170525
' O PGD ' 66.3 'track' 47.562356 2.170599
' O PGD ' 66.3 'track' 47.562317 2.170672
' O PGD ' 66.3 'track' 47.562278 2.170744
' O PGD ' 66.3 'track' 47.56224 2.170817
' O PGD ' 66.3 'track' 47.562201 2.17089
' O PGD ' 66.3 'track' 47.562163 2.170962
' O PGD ' 66.3 'track' 47.562125 2.171034
' O PGD ' 'nan' 'track' 47.562085 2.171109
' O PGD ' 66.2 'track' 47.562046 2.171182
' O PGD ' 66.3 'track' 47.562008 2.171255
It must look like:
'Flags' 'Dist[km]' 'SoT' 'Lat.' 'Long.'
' O PGD ' 66.4 'track' 47.562584 2.170151
' O PGD ' 66.4 'track' 47.562544 2.170225
' O PGD ' 66.4 'track' 47.562505 2.170297
' O PGD ' 66.3 'track' 47.562433 2.170453
' O PGD ' 66.3 'track' 47.562395 2.170525
' O PGD ' 66.3 'track' 47.562356 2.170599
' O PGD ' 66.3 'track' 47.562317 2.170672
' O PGD ' 66.3 'track' 47.562278 2.170744
' O PGD ' 66.3 'track' 47.56224 2.170817
' O PGD ' 66.3 'track' 47.562201 2.17089
' O PGD ' 66.3 'track' 47.562163 2.170962
' O PGD ' 66.3 'track' 47.562125 2.171034
' O PGD ' 66.2 'track' 47.562046 2.171182
' O PGD ' 66.3 'track' 47.562008 2.171255
Thanks in advance.
  2 comentarios
Matz Johansson Bergström
Matz Johansson Bergström el 17 de Jul. de 2014
Could you upload the raw data as a .mat file? It would be so much easier to debug.

Iniciar sesión para comentar.

Respuesta aceptada

Andrei Bobrov
Andrei Bobrov el 17 de Jul. de 2014
data = raw(:,[3,14,17,20,21]);
ll = ~cellfun(@(x)strcmp('nan',x),data(:,2));
out = data(ll,:);
  2 comentarios
Yuliia
Yuliia el 17 de Jul. de 2014
Editada: Andrei Bobrov el 17 de Jul. de 2014
Thanks a lot. It works for me. But, I have a question. What does this line do?
ll=~cellfun(@(x)strcmp('nan',x),data(:,2));
I understand it like it searches for indexes of 'nan' and then command
out = data(ll,:);
displays these values. But, I want to filter by all the conditions at the same time. I use this:
ll=~cellfun(@(x)strcmp('nan',x),data(:,2));
ll2=~cellfun(@(x)strcmp('search',x),data(:,3));
ll3=~cellfun(@(x)strcmp(' O PGD ',x),data(:,1));
ll4=~cellfun(@(x)strcmp('memory',x),data(:,3));
out4=data(ll&ll2&ll3&ll4,:);
As a result, I don't receive needed values, not all rows with 'memory' deleted. How to write correctly to display data filtered by all these conditions?
Andrei Bobrov
Andrei Bobrov el 17 de Jul. de 2014
Editada: Andrei Bobrov el 17 de Jul. de 2014
Hi Yuliia! For your case:
data = raw(:,[3,14,17,20,21]);
ll = ~any([strcmp('nan',data(:,2)),...
ismember(data(:,[1,3]),{' O PGD ','search','memory'})],2);
out = data(ll,:);
or
data = raw(:,[3,14,17,20,21]);
d = data(:,1:3);
ll = false(size(d));
l0 = find(cellfun(@ischar,d));
ll(l0) = ismember(d(l0),]),{' O PGD ','search','nan','memory'});
out = data(~any(ll,2),:);

Iniciar sesión para comentar.

Más respuestas (1)

Matz Johansson Bergström
Matz Johansson Bergström el 17 de Jul. de 2014
Andrei beat me to it (again), but here is how you could answer using a loop.
keep_cols = [3, 14, 17, 20, 21];
tmp = raw(:, keep_cols); %copy the columns we wish to keep
j = 1;
for i = 1:size(raw, 1)
if ~strcmp(raw(i, 14), 'nan') %filter out the not-a-number distance entries
new_raw(j, :) = tmp(i, :); %copy to new entry in new_raw
j = j+1;
end
end
new_raw contains the filtered data. Preferably you would use cellfun, because it is vectorized, so it is usually much faster.

Categorías

Más información sobre Standard File Formats en Help Center y File Exchange.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by