To delete rows from a cell array specifying conditions

조회 수: 3 (최근 30일)
Yuliia
Yuliia 2014년 7월 17일
편집: Andrei Bobrov 2014년 7월 17일
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
Matz Johansson Bergström
Matz Johansson Bergström 2014년 7월 17일
Could you upload the raw data as a .mat file? It would be so much easier to debug.
Yuliia
Yuliia 2014년 7월 17일
Here it is

댓글을 달려면 로그인하십시오.

채택된 답변

Andrei Bobrov
Andrei Bobrov 2014년 7월 17일
data = raw(:,[3,14,17,20,21]);
ll = ~cellfun(@(x)strcmp('nan',x),data(:,2));
out = data(ll,:);
  댓글 수: 2
Yuliia
Yuliia 2014년 7월 17일
편집: Andrei Bobrov 2014년 7월 17일
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 2014년 7월 17일
편집: Andrei Bobrov 2014년 7월 17일
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),:);

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Matz Johansson Bergström
Matz Johansson Bergström 2014년 7월 17일
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.

카테고리

Help CenterFile Exchange에서 Database Toolbox에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by