Find consecutive values in a vector that are above a threshold
조회 수: 20 (최근 30일)
이전 댓글 표시
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
채택된 답변
Matt Kindig
2013년 5월 31일
편집: Matt Kindig
2013년 6월 4일
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
Peacerich
2017년 10월 5일
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));
추가 답변 (1개)
Youssef Khmou
2013년 5월 31일
편집: Youssef Khmou
2013년 5월 31일
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
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!