Control Break Processing

1 Ansicht (letzte 30 Tage)
luke
luke am 20 Jul. 2011
[EDIT: 20110720 16:05 CDT - reformat - WDR]
I have 3 column vectors (Date1 Date2 and Error) and what I want to do is create the column named Target. Target is a 1 if it is the smallest error by Date1 and Date2 AND error is < .10 otherwise its a 0.
I can do this using for loops, BUT I was wondering if I can do this using logical indexing....I am guessing that this will be faster since I won't have to nest3 for loops.
Date1 Date2 error Target
'06-Nov-2000' '16-Dec-2000' 0.47 0
'06-Nov-2000' '16-Dec-2000' 0.41 0
'06-Nov-2000' '16-Dec-2000' 0.29 0
'06-Nov-2000' '16-Dec-2000' 0.14 0
'06-Nov-2000' '16-Dec-2000' 0.03 1
'06-Nov-2000' '16-Dec-2000' 0.18 0
'06-Nov-2000' '18-Nov-2000' 0.03 1
'06-Nov-2000' '18-Nov-2000' 0.31 0
'06-Nov-2000' '18-Nov-2000' 0.44 0
'06-Nov-2000' '18-Nov-2000' 0.45 0
'06-Nov-2000' '18-Nov-2000' 0.44 0
'06-Nov-2000' '18-Nov-2000' 0.44 0
'06-Nov-2000' '18-Nov-2000' 0.45 0
'06-Nov-2000' '18-Nov-2000' 0.45 0
'07-Nov-2000' '18-Nov-2000' 0.36 0
'07-Nov-2000' '18-Nov-2000' 0.09 1
'07-Nov-2000' '18-Nov-2000' 0.15 0
'07-Nov-2000' '18-Nov-2000' 0.38 0
'07-Nov-2000' '18-Nov-2000' 0.48 0
'07-Nov-2000' 18-Dec-2000' 0.50 0
'07-Nov-2000' 18-Dec-2000' 0.01 1
'07-Nov-2000' 18-Dec-2000' 0.15 0

Akzeptierte Antwort

Fangjun Jiang
Fangjun Jiang am 20 Jul. 2011
I have one solution but it still requires a for-loop.
raw={'06-Nov-2000' '16-Dec-2000' 0.47 0
'06-Nov-2000' '16-Dec-2000' 0.41 0
'06-Nov-2000' '16-Dec-2000' 0.29 0
'06-Nov-2000' '16-Dec-2000' 0.14 0
'06-Nov-2000' '16-Dec-2000' 0.03 1
'06-Nov-2000' '16-Dec-2000' 0.18 0
'06-Nov-2000' '18-Nov-2000' 0.03 1
'06-Nov-2000' '18-Nov-2000' 0.31 0
'06-Nov-2000' '18-Nov-2000' 0.44 0
'06-Nov-2000' '18-Nov-2000' 0.45 0
'06-Nov-2000' '18-Nov-2000' 0.44 0
'06-Nov-2000' '18-Nov-2000' 0.44 0
'06-Nov-2000' '18-Nov-2000' 0.45 0
'06-Nov-2000' '18-Nov-2000' 0.45 0
'07-Nov-2000' '18-Nov-2000' 0.36 0
'07-Nov-2000' '18-Nov-2000' 0.09 1
'07-Nov-2000' '18-Nov-2000' 0.15 0
'07-Nov-2000' '18-Nov-2000' 0.38 0
'07-Nov-2000' '18-Nov-2000' 0.48 0
'07-Nov-2000' '18-Dec-2000' 0.50 0
'07-Nov-2000' '18-Dec-2000' 0.01 1
'07-Nov-2000' '18-Dec-2000' 0.15 0};
% Date1 is your first column, nx1 cell array of strings
% Date2 is your second column, nx1 cell array of strings.
% Err is your third column, nx1 double array
Date1=raw(:,1);
Date2=raw(:,2);
Err=cell2mat(raw(:,3));
RawTarget=cell2mat(raw(:,4));
Target=false(size(Err));
Date=cellstr(cell2mat([Date1,Date2]));
UniqueDate=unique(Date);
for k=1:length(UniqueDate)
Index=ismember(Date,UniqueDate(k));
Loc=find(Index);
[Dummy,MinIndex]=min(Err(Index));
Target(Loc(MinIndex))=true;
end
Target=and(Target, Err<0.1);
all(Target==RawTarget)
  5 Kommentare
Fangjun Jiang
Fangjun Jiang am 21 Jul. 2011
It is correct. I included your data in the code. Notice the last line returns 1.
luke
luke am 22 Jul. 2011
I stand corrected. I must have changed something in the code.
Thanks! Now I need to go thru this so that I understand how it works

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Nathan Greco
Nathan Greco am 20 Jul. 2011
Here's a dirty method, but no handwritten loops as requested.
Assume tmp contains your 22x3 cell array of data (the 4th column will be computed).
%storing strings as unique identifiers
tmp2 = cellfun(@(x,y)[x y],tmp(:,1),tmp(:,2),'un',0);
%get unique blocks:
[m m m] = unique(tmp2);
%get error column:
err = [tmp{:,3}];
%get target:
target = arrayfun(@(x)any(ismember(accumarray(m,err,[],@(x)min(x)),x)&x<.10),err,'un',0)';
%add target to original cell array:
tmp = [tmp target];
Hopefully this helps. It does the trick, but not sure about the speed. Anyone want to speed mine up?
Also note that loops don't necessarily mean SLOW anymore in Matlab. Try some timings on solutions provided versus your own to see what is best for you.

Kategorien

Mehr zu Matrix Indexing finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by