Code for Counting and Lookup

I have imported a csv file into MATLAB. The number of rows in the table is 81 so there is a long series of '1's and '0's in the single column. I want to check that whenever the consecutive number of rows with '1's is greater than 4, then flag it and note the time stamp corresponding to the first '1' for that consecutive rows of '1'. Do this for every series of 1's appearing successively for more than 4 times i.e obtain the corresponding time. The time stamps are given in the column Var1.

4 Comments

What did you try so far? (make sure to post your code as formatted text, and not as a screenshot)
If you want a solution with your own data you should attach your data to your question in a mat file.
x=81
y=0
for i=1:x
if T.Var3(i)==0
y=y+0
else if T.Var3(i)==1 && T.Var3(i+1)==1 && T.Var3(i+2)==1 && T.Var3(i+3)==1
y=T.Var1(i)
end
end
end
Did you mean elseif?
You forgot to format the code, and you forgot to account for the length of your variable. What happens when i is equal to the length of the table?
x=78
y=0
for i=1:x
if T.Var3(i)==0
y=y+0
else if T.Var3(i)==1 && T.Var3(i+1)==1 && T.Var3(i+2)==1 && T.Var3(i+3)==1
y=T.Var1(i)
end
end
end

Sign in to comment.

 Accepted Answer

Adam Danz
Adam Danz on 4 Oct 2020
Edited: Adam Danz on 4 Oct 2020
Here's a demo.
v is the input vector of 1s and 0s (or Trues and Falses)
r is the output vector of row numbers in v that start 4+ consecutive 1s.
% Demo data: v is a vec of 1s and 0s (or Trues and Falses)
A = [1 0 0 1 1 1 1 1 1 0 0 1 1 1 0 1 0 0 0 1 1 1 1 0 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 1 1 1 1]';
% Length of each group of consecutive 1s
B = diff(find([0;A(:);0]==0))-1;
B(B==0) = [];
% Index of 1st '1' in each group of consecutive 1s
firstIdx = find(diff([0;A(:)])==1);
% Row number of the first 1 in groups of 4 or more consecutive 1s
minConsec = 4;
r = firstIdx(B >= minConsec);
Result:
r =
4
20
25
42
48

14 Comments

Thanks, Rik.
"The dataset is large. I am using a table T(1048570x542table) and using the code. If the table size is small then it gives value for r but for my case where table size is large it gives the error the logical indices contain a true value outside the bounds of the array"
The error is not related to data size. It's likely caused by 1 or more NaN values within the vector of 1s and 0s. The example below inserts 1 NaN value in v and results in the same error.
% Demo data: v is a vec of 1s and 0s (or Trues and Falses)
A = [1 0 0 1 1 1 1 1 1 0 0 1 1 1 0 1 0 0 0 1 1 1 1 0 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 1 1 1 1]';
A(3) = NaN;
% [ insert the code from my answer]
% Result:
r = firstIdx(B >= minConsec);
The logical indices contain a true value outside of the array bounds.
To fix this, you can replace NaN values with 0 (or false)
A(isnan(A)) = 0; % or = false
% Then run the rest of the code.
It works for me. Thanks for the help
Hi
I need help in counting the consecutive number of 1's. Here I have defined minConsec=4 for 4 consective 1's. How do I count the total number of 1's the series of consecutive 1's.
@Waqas Siddique Have any of the answers to your previous questions been helpful?
Yes they were helpful. Can you help me with my new querry.
Then why did you not accept any of them?
I have accepted the one most useful for me
Still 9 threads without an accepted answer. Maybe none of those have a working solution, but somehow I doubt that.
Rik, I understood the one that worked for me. Now I have a problem in the same question. I have to count the total number of 1's in the series of consecutive 1's. I believe the length of consecutive 1's is stored in the variable B as provided in the solution above. So I need to retrieve and display the length,
% Length of each group of consecutive 1s
B = diff(find([0;A(:);0]==0))-1;
B(B==0) = [];
Waqas, I'm not sure why you didn't like my answer below that lets you "retrieve and display the length" as you asked for, plus gives you the starting and stopping location of each segment.
I do not understand how it is displaying the length.
>I need help in counting the consecutive number of 1's.
Look at variable B in my answer. A comment in my answer describes B as "Length of each group of consecutive 1s".

Sign in to comment.

More Answers (1)

If you have the Image Processing Toolbox, you can also use bwareaopen() and regionprops():
A = [1 0 0 1 1 1 1 1 1 0 0 1 1 1 0 1 0 0 0 1 1 1 1 0 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 1 1 1 1]';
A = bwareaopen(logical(A), 4); % Just extract runs of 4 or longer.
props = regionprops(A, 'PixelIdxList') % Find indexes of all runs of 1's.
% Done! Results are in the table.
% Print out all runs where the length is 4 or more
startingIndexes = zeros(height(props), 1);
for k = 1 : height(props)
startingIndexes(k) = props(k).PixelIdxList(1);
fprintf('Region %d starts at index %d.\n', ...
k, startingIndexes(k));
end
Gives the same results as Adam's solution.
Region 1 starts at index 4.
Region 2 starts at index 20.
Region 3 starts at index 25.
Region 4 starts at index 42.
Region 5 starts at index 48.
If you also want the lengths of the runs in addition to their starting index, just ask regionprops() for 'Area':
props = regionprops(A, 'PixelIdxList', 'Area') % Find lengths and indexes of all runs of 1's.
allLengths = [props.Area]

Community Treasure Hunt

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

Start Hunting!