Msen Rezaee February 2016

How to extract vectors of consecutive numbers?

Suppose that I have a Q vector which is defined as Q = [1 2 3 4 5 8 9 10 15]; and I would like to find a way to extract different vectors of consecutive numbers and also a vector for the rest of the elements. So my result would be like:

q1 = [1 2 3 4 5];
q2 = [8 9 10 ];
q3 = [15];

Answers


Dan February 2016

You can do this using diff, cumsum and accumarray:

q = accumarray(cumsum([1, diff(Q)~=1])', Q', [], @(x){x})

which returns:

{[1,2,3,4,5];
 [8,9,10];
 [15]}

i.e. q{1} gives you [1,2,3,4,5] etc which is a far cleaner solution to having separately named vectors. But if you really really wanted to have them, and you know exactly how many groups you will get out, you can do it as follows:

[q1,q2,q3] = q{:};

Explanation:

accumarray will apply an aggregation function (4th input) to elements of a vector (2nd input) based on groupings specified in another vector (1st input).

To use the notation in the docs:

sub = cumsum([1, diff(Q)~=1])';
val = Q';
fun = @(x){x};

Note that sub needs to start from 1. The idea is to use diff to find elements that are consecutive (i.e. where Q(i+1) - Q(i) == 1) which is vectorized using the diff function. By specifying diff(Q)~=1 we can find the breaks between groups of consecutive numbers (concatenating the 1 at the beginning to force a break at the start). cumsum then just converts these breaks into vector of in the right form for sub i.e.

sub = [1 1 1 1 1 2 2 2 3]

The aggregation function we specify is just cell concatenation.

Post Status

Asked in February 2016
Viewed 1,108 times
Voted 6
Answered 1 times

Search




Leave an answer