Find consecutive values in a vector that are above a threshold

21 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
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);

Categories

Find more on Matrices and Arrays in Help Center and File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!