# How to find consecutive values above a certain threshold?

115 views (last 30 days)
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

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)

James on 3 Oct 2018
Can you explain how this solution works?
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 on 16 Feb 2019
Muhammad: See my solution below. Just ask regionprops for PixelIdxList or PixelList - that will be the indexes.

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

#### 1 Comment

Kristine on 22 Jul 2015
Thank you!

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

Show 1 older comment
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
...
Azzi Abdelmalek on 22 Jul 2015
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?

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;

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 on 22 Jul 2015
You'd need to download that "RunLength" function from the File Exchange using the link he gave you.
Kristine on 22 Jul 2015
Oh I didn't see the link. Thank you Image Analyst!!

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
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