Azzera filtri
Azzera filtri

Find a series of consecutive numbers in a vector

112 visualizzazioni (ultimi 30 giorni)
Hello, I have a small problem I am trying to solve on Matlab, but I am a stuck.
I have a vector containing timestamps: [34 35 36 78 79 80 81 82 84 85 86 102 103 104 105 106 107 201 202 203 204 ...]
And I would like to find the timestamp which is followed by at least 5 consecutive numbers after it. So in my example, the answer would be 102, because it is the first number which is followed by 5 consecutive numbers.
I tried many things using diff(), but I cannot find a simple way to get that result.
If anyone can help, it would be greatly appreciated.
Thank you!

Risposta accettata

Roger Stafford
Roger Stafford il 6 Set 2013
Yet another method. Let t be your timestamp row vector.
N = 5; % Required number of consecutive numbers following a first one
x = diff(t)==1;
f = find([false,x]~=[x,false]);
g = find(f(2:2:end)-f(1:2:end-1)>=N,1,'first');
first_t = t(f(2*g-1)); % First t followed by >=N consecutive numbers
  2 Commenti
Caixia Liu
Caixia Liu il 10 Apr 2018
Modificato: Caixia Liu il 10 Apr 2018
Thanks for your codes. But it fails when the first index is actually the result.
Nurul Ain Basirah Zakaria
Nurul Ain Basirah Zakaria il 12 Giu 2021
hi, what if, i want something like this:
to find the consecutive value below -1
2.0 2.5 2.1 1.3 1.4 -1.0 -2.1 -1.2 -1.5 -2.1 2.0 3.2 3.0 -1.0 -4.0 -2.1 -1.45 -1.20 -2.0 3.0 2.5 1.2
the first consecutive negative value is categorize as first event and second consecutive negative value is the second event,
then i want to calculate the mean value for each event;
sum of -1.0 -2.1 -1.2 -1.5 -2.1, divide by 5, as there are 5 num of -ve value for first event,
and the second event,
sum of -1.0 -4.0 -2.1 -1.45 -1.20 -2.0, divide by 6, as the are 6 num of -ve value for second event
can i do this in matlab?

Accedi per commentare.

Più risposte (6)

Laurent
Laurent il 5 Set 2013
The following will give the lengths of the consecutive sequences of your vector:
q=yourvector;
a=diff(q);
b=find([a inf]>1);
c=diff([0 b]); length of the sequences
d=cumsum(c); endpoints of the sequences
  3 Commenti
Laurent
Laurent il 5 Set 2013
Modificato: Laurent il 5 Set 2013
This is what I get:
>> c
c =
3 5 3 6 4
which are the lengths of the sequences.
>> d
d =
3 8 11 17 21
which is where the sequences end.
Then with a 'find(c>5)' you will know the location of the sequences larger than 5. Then from d you can deduce where the start of this sequence is.
Or did I misunderstand the question?
Image Analyst
Image Analyst il 5 Set 2013
No, sorry, I misunderstood your comment. I thought your endpoints was both endpoints - the starting and stopping indexes, but it's only where they stop.

Accedi per commentare.


Jan
Jan il 8 Set 2013
Modificato: Jan il 8 Set 2013
This is almost a run-length problem:
x = [34 35 36 78 79 80 81 82 84 85 86 102 103 104 105 106 107 201 202 203 204];
[b, n, idx] = RunLength(x - (1:length(x)));
match = (n > 5);
result = x(idx(match));

David Sanchez
David Sanchez il 5 Set 2013
my_array = [34 35 36 78 79 80 81 82 84 85 86 102 103 104 105 106 107 201 202 203 204];
my_num = 0;
consec = 1;
for k= 1:(numel(my_array)-1)
if ( my_array(k+1) == (my_array(k) + 1) )
consec = consec +1;
if consec > 5
my_num = my_array(k-4);
break
end
else
consec = 1;
end
end
my_num =
201
  1 Commento
David Sanchez
David Sanchez il 5 Set 2013
I used this array instead:
my_array = [34 35 36 78 79 80 81 82 84 85 86 102 103 104 105 108 109 201 202 203 204 205 206 207 210];
my_num =
201
With the code above, the answer will be:
my_num =
102

Accedi per commentare.


JEM
JEM il 30 Mag 2017
Modificato: Walter Roberson il 5 Giu 2021
Easier like this
t=[34 35 36 78 79 80 81 82 84 85 86 102 103 104 105 106 107 201 202 203 204];
% search for the derivative 1 1 1 1 1 corresponding to 5 consecutive values
result = t(findstr(diff(t),[1 1 1 1 1]));
  2 Commenti
dpb
dpb il 16 Ott 2018
The difference vector of ones will be N-1 length to be found, not N, though. Five differences==1 will correspond to six consecutive values incremented by one.
Sinem Balta Beylergil
Sinem Balta Beylergil il 5 Giu 2021
One correction and it works perfectly:
t = find(overlapR==1);
result = t(intersect(diff(t),[1 1 1 1 1]))
PS [1 1 1 1 1] can be written as ones(1,5) and 5 can be any number of repetitions you want.

Accedi per commentare.


Andrei Bobrov
Andrei Bobrov il 5 Set 2013
Modificato: Andrei Bobrov il 5 Set 2013
a = [34 35 36 78 79 80 81 82 84 85 86 102 103 104 105 106 107 201 202 203 204]
n = 6 % number consecutive numbers
k = [true;diff(a(:))~=1 ];
s = cumsum(k);
x = histc(s,1:s(end));
idx = find(k);
out = a(idx(x==n))
  2 Commenti
Andrew Newell
Andrew Newell il 23 Apr 2014
Doesn't work if a contains negative numbers.
Martti K
Martti K il 27 Ott 2015
Modificato: Martti K il 27 Ott 2015
To me it seems to work well with negative numbers also, but not with decreasing sequencies. In order to take the decreasing sequencies, use
k = [true;diff(a(:))~=-1];
In order to take at_least n consecutive numbers, use
out = a(idx(x>=n))

Accedi per commentare.


Fahd Elabd
Fahd Elabd il 30 Dic 2020
% Here I have get the first and last numbers of consecutive group in iOnes array,
iOnes = [34 35 36 78 79 80 81 82 84 85 86 102 103 104 105 106 107 201 202 203 204];
k=1;
j=1;
for i=1:length(iOnes)-1
if iOnes(i+1)-iOnes(i)==1 % means the next point is follwoing the current point
firstOnes(k) = iOnes(j);
lastOnes(k) = iOnes(i+1);
else
j=i+1;
k=k+1;
end
end

Categorie

Scopri di più su Loops and Conditional Statements in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by