MATLAB Answers

How to find consecutive values above a certain threshold?

115 views (last 30 days)
Kristine
Kristine on 22 Jul 2015
Edited: Lane Foulks on 15 Nov 2019
Hi.
I'm picking out values from a hourly data set, and I want to pick out values that are above 12 at least three consecutive times. Any tips on how I can do this?
example: A=[0 1 2 5 7 8 13 17 28 11 6 0 2 1 4]
I want to put the three values 13 17 28 into a vector.
Help is greatly appreciated!
- Kristine

  0 Comments

Sign in to comment.

Accepted Answer

Azzi Abdelmalek
Azzi Abdelmalek on 22 Jul 2015
Edited: Azzi Abdelmalek on 22 Jul 2015
A=[0 1 2 5 7 8 13 17 28 11 6 0 2 1 40 55 88 47 4 44 ]
idx=A>12;
ii1=strfind([0 idx 0],[0 1]);
ii2=strfind([0 idx 0],[1 0])-1;
ii=(ii2-ii1+1)>=3;
out=arrayfun(@(x,y) A(x:y),ii1(ii),ii2(ii),'un',0);
celldisp(out)

  9 Comments

Show 6 older comments
Muhammad Shahid Iqbal
Muhammad Shahid Iqbal on 15 Feb 2019
Hello guys, this was very helpful but how about if we also need the index of those consective values which are greater than threshold???
Image Analyst
Image Analyst on 16 Feb 2019
Muhammad: See my solution below. Just ask regionprops for PixelIdxList or PixelList - that will be the indexes.

Sign in to comment.

More Answers (4)

Image Analyst
Image Analyst on 22 Jul 2015
Kristine:
This pretty easy and straightforward if you have the Image Processing Toolbox to identify stretches where the numbers are above the threshold and measure their lengths. Then just save those stretches of numbers into cells of a cell array.
% Define sample data and a threshold value.
A=[0 1 2 5 7 8 13 17 28 11 6 0 2 1 4 91 49 37 79 9 100 101 3]
threshold = 12;
% Find logical vector where A > threshold
binaryVector = A > 12
% Label each region with a label - an "ID" number.
[labeledVector, numRegions] = bwlabel(binaryVector)
% Measure lengths of each region and the indexes
measurements = regionprops(labeledVector, A, 'Area', 'PixelValues');
% Find regions where the area (length) are 3 or greater and
% put the values into a cell of a cell array
for k = 1 : numRegions
if measurements(k).Area >= 3
% Area (length) is 3 or greater, so store the values.
ca{k} = measurements(k).PixelValues;
end
end
% Display the regions that meet the criteria:
celldisp(ca)
In the command window, this is what you'll see:
A =
0 1 2 5 7 8 13 17 28 11 6 0 2 1 4 91 49 37 79 9 100 101 3
binaryVector =
0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 1 1 1 1 0 1 1 0
labeledVector =
0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 2 2 2 2 0 3 3 0
numRegions =
3
ca{1} =
13 17 28
ca{2} =
91 49 37 79

Stephen Cobeldick
Stephen Cobeldick on 22 Jul 2015
Edited: Stephen Cobeldick on 26 Jul 2015
Here is a conceptually very simple method (I changed the third value to 20 as well, to provide a sequence of values > 12 but shorter then three):
>> N = 12;
>> A = [0,1,20,5,7,8,13,17,28,11,6,0,2,1,4];
>> idx = [true,A(1:end-1)>N] & A>N & [A(2:end)>N,true];
>> idx = [false,idx(1:end-1)] | idx | [idx(2:end),false];
>> A(idx)
ans =
13 17 28

  4 Comments

Show 1 older comment
Kristine
Kristine on 22 Jul 2015
Okay I'm probably being annoying right now, but how do I do it if my time series looks like this:
A = 504223x3 double:
39904 0 9
39904 0.0417 7
39904 0.0833 13
39904 0.1250 14
39904 0.1667 16
39904 0.2083 10
...
Kristine
Kristine on 22 Jul 2015
Same question as above, but I also need to include the date and hour for my values above 12. Does that make sense?

Sign in to comment.


Jan
Jan on 22 Jul 2015
A = [0 1 2 5 7 8 13 17 28 11 6 0 2 1 4];
[B, N] = RunLength(A > 12);
B(N < 3) = false;
mask = RunLength(B, N);
Result = A(mask);

  3 Comments

Kristine
Kristine on 22 Jul 2015
I tried running what you wrote above, but it gave me the error: Undefined function 'RunLength' for input arguments of type 'logical'. Could it be that I don't have that function or because I need to change the vector from double to something else? Thank you for helping!!
Image Analyst
Image Analyst on 22 Jul 2015
You'd need to download that "RunLength" function from the File Exchange using the link he gave you.
Kristine
Kristine on 22 Jul 2015
Oh I didn't see the link. Thank you Image Analyst!!

Sign in to comment.


Lane Foulks
Lane Foulks on 15 Nov 2019
Edited: Lane Foulks on 15 Nov 2019
A=[0 1 2 5 7 8 13 17 28 11 6 0 2 1 4 14 18 0 2 16 15 18 13 0 ] % added a passing and failing block above threshold
Adiff = diff(A>12);
ind_start = find(Adiff==1);
ind_stop = find(Adiff==-1);
block_length = ind_stop-ind_start; % list of consecutive section lengths
blocks_ind = find(block_length>2)% list of blocks above min length
for ii = 1:numel(blocks_ind) % loops through each block
A(ind_start(blocks_ind(ii))+1:ind_stop(blocks_ind(ii)))
end

  0 Comments

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!