find and store index for consecutive numbers

14 views (last 30 days)
Richard on 11 Mar 2013
Commented: Dean Ranmar on 30 Nov 2016
Consider the following:
Jday = datenum('2009-01-01 00:00','yyyy-mm-dd HH:MM'):1:...
datenum('2009-12-31 23:00','yyyy-mm-dd HH:MM');
DateV = datevec(Jday);
dat = 1+(10-1).*rand(length(Jday),1);
noise = 10*sin(2*pi*Jday/32)+20;
for i = 1:size(dat,2);
dat2(:,i) = dat(:,i)+noise';
nan_dat = floor(100+(300-1).*rand(50,1));
dat2(nan_dat) = nan;
From 'dat2' I would like to find the maximum number of days in each month (denoted by DateV(:,2)) where dat2 is greater than 30. In addition I would like the number of days to be equal in each month so if we have 10 values greater than 30 in month 1 and then only 5 values greater than 30 in month 2 then we should only take the first 5 values greater than 30 in both months. This should then be applied to all months. Note: missing values are present in this series.
Richard on 11 Mar 2013
yes maximum number of consecutive days. With regards to the nans and the specific example you have shown this would be one value over 30 seeing as nan is not over 30. So, the entire point here is to find the greatest number of consecutive days in each month where the values are over 30 and no missing data is present. Hope I am clear in my intentions.
Jan on 11 Mar 2013
Edited: Jan on 11 Mar 2013
Your intention is fairly clear. What is the question? What kind of help do you expect?

Sign in to comment.

Answers (1)

ChristianW on 11 Mar 2013
I guess your problem is identifying same areas in a vector. Therefore you may use this function:
Isame = @(x) [1; find(diff(x))+1; length(x)]; % index for same areas
An example is
x = [2 2 2 2 1 6 6 6 0]';
Idx = Isame(x) % Idx = [1 5 6 9 9]
The first area starts at index 1, the second at index 5, etc. As last index I added the x(end)-index. This is helpful in a loop.
In this way you can loop the same area's instead of every x element. I would loop the months like that and also calculate area's greater than 30 (Isame(X>30)). For the area-length (number of days) use diff(Isame(X>30)). Do not forget there are true and false area's for X>30.
Dean Ranmar
Dean Ranmar on 30 Nov 2016
This function is very useful. I wanted to do something different - find consecutive integers in a vector. From Isame, I created Idiff:
Idiff = @(x) [1; find(diff(x)-1)+1; length(x)];
And, if I then do the following to vector x3
x3 = [16 17 18 30 31 46 47 48 49 50 51 65 78 79 80]; Idx = Idiff(x3); Ldx = diff(Idx);
I get first a vector identifying the indices of elements which are not consecutive and then the lengths of sequences of consecutive integers.
Idx = [1 4 6 12 13 16 16]; Ldx = [3 2 6 1 3 0];
I ignore the last two entries in Idx and the last one in Ldx. (I could truncate the vectors to make this more elegant, I guess.)
Dean Ranmar
Dean Ranmar on 30 Nov 2016
BTW, in MATLAB 2015b, you have to declare x first or you get an error:
x = []';
(I should have had a transpose on the x3 vector above.)

Sign in to comment.


Find more on Dates and Time 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!