Find consecutive values in a vector that are above a threshold

9 views (last 30 days)
Hi everyone,
I have a vector of monthly values. I would now like to identify periods of months where the values exceeded my threshold for 5 months. I know I can find all the individual months with the find function but how do I add this extra condition saying, only show me their position if five months in a row exceeded the threshold?
thank you so much for any hint. Sandra

Accepted Answer

Matt Kindig
Matt Kindig on 31 May 2013
Edited: Matt Kindig on 4 Jun 2013
One way:
s = RandStream('mcg16807','Seed',0);
RandStream.setDefaultStream(s); %set seed so example is reproducible
monthdata = rand(1,30); %random data
threshold = 0.4; %for example
aboveThreshold = (monthdata > threshold); %where above threshold
%aboveThreshold is a logical array, where 1 when above threshold, 0, below.
%we thus want to calculate the difference between rising and falling edges
aboveThreshold = [false, aboveThreshold, false]; %pad with 0's at ends
edges = diff(aboveThreshold);
rising = find(edges==1); %rising/falling edges
falling = find(edges==-1);
spanWidth = falling - rising; %width of span of 1's (above threshold)
wideEnough = spanWidth >= 5;
startPos = rising(wideEnough); %start of each span
endPos = falling(wideEnough)-1; %end of each span
%all points which are in the 5-month span (i.e. between startPos and endPos).
allInSpan = cell2mat(arrayfun(@(x,y) x:1:y, startPos, endPos, 'uni', false));
EDIT: Made more robust for case where first point is above threshold as well.
  4 Comments
Sandra
Sandra on 3 Jun 2013
I have the processing toolbox. Thank you for this solution. A really neat approach!
Peacerich
Peacerich on 5 Oct 2017
For those of you who don't have the Image Processing Toolbox you can rewrite those parts as follows:
aboveThreshold = (monthdata > threshold);
thresholdChange = [aboveThreshold(1) diff(aboveThreshold)];
thresholdChange(thresholdChange==-1) = 0;
spanLocs = cumsum(thresholdChange);
spanLocs(~aboveThreshold) = 0;
aboveThresholdIndex = find(aboveThreshold==1);
notConsecutiveIndex = [true diff(aboveThresholdIndex) ~= 1];
sumIndex = cumsum(notConsecutiveIndex);
spanLength = histc(sumIndex, 1:sumIndex(end));
goodSpans = find(spanLength>=5);
allInSpans = find(ismember(spanLocs, goodSpans));

Sign in to comment.

More Answers (1)

Youssef  Khmou
Youssef Khmou on 31 May 2013
Edited: Youssef Khmou on 31 May 2013
hi you can find function with multiple output that show the indices :
v=1:10;
[r,c]=find(r>5);
c represents the indices not the values , to make it more clear :
v=wrev(v);
[r,c]=find(r>5);

Tags

Community Treasure Hunt

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

Start Hunting!