Sort values of a vector in an array according to gaps
2 views (last 30 days)
Show older comments
Marc Jakobi
on 13 Dec 2013
Edited: Andrei Bobrov
on 13 Dec 2013
Hi. I have a vector that looks something like this:
A = [1; 2; 3; 4; 6; 7; 8; 9; 10; 12; 13; 14; 15; 16; 17; 19; 20];%and so on
and another vector containing the gaps in A:
B = [5; 11; 18]
In this example, the values 5, 11 and 18 are missing. The vector I am working with is a lot longer and has the values missing in random places.
What I want to do is create an array out of A that starts a new column every time there's a gap:
CELL = {[1; 2; 3; 4], [6; 7; 8; 9; 10], [12; 13; 14; 15; 16; 17], [19; 20]};
I wrote a loop that does just that, but because A is so long, my computer eventually freezes. Any suggestions for a faster method using logical operations or something (I'm not so good with those, yet).
Thanks in advance!
0 Comments
Accepted Answer
Azzi Abdelmalek
on 13 Dec 2013
A = [1; 2; 3; 4; 6; 7; 8; 9; 10; 12; 13; 14; 15; 16; 17; 19; 20]
idx=diff(A);
ii2=unique([find(idx>1) ;numel(A)]);
ii1=[1 ;ii2(1:end-1)+1];
out=arrayfun(@(x,y) A(x:y),ii1,ii2,'un',0);
celldisp(out)
0 Comments
More Answers (2)
Image Analyst
on 13 Dec 2013
How many elements are in B? A for loop shouldn't take that long if it's under ten million or so. The time is probably taken up in creating the cell array's cells rather than the for loop iteration itself. I can do a for loop of 10 million iterations in 0.03 seconds, so the for loop itself is fast. It's creating the cells that takes time.
Possible solution to speed it up: Can you take diff(B) to find out how long the longest stretch will be and then preallocate a normal int32 rectangular array to hold the output? I know that you'll have a ragged right edge but you can just flag those with some special number like -999 or something so you know they're not to be used.
Andrei Bobrov
on 13 Dec 2013
Edited: Andrei Bobrov
on 13 Dec 2013
A = [1; 2; 3; 4; 6; 7; 8; 9; 10; 12; 13; 14; 15; 16; 17; 19; 20];
B = [5; 11; 18];
i0=zeros(numel([A(:);B(:)]),1);
i0(B)=1;
i1=cumsum(i0)+1;
CELL1 = accumarray(i1(A),A,[],@(x){x});
or in one line:
CELL1 = accumarray(cumsum([true;diff(A)>1]),A,[],@(x){x});
0 Comments
See Also
Categories
Find more on Logical in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!