Find consecutive values in a vector that are above a threshold
21 views (last 30 days)
Show older comments
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
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
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));
More Answers (1)
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);
0 Comments
See Also
Categories
Find more on Matrices and Arrays 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!