How do I extract the first non-zero value from array after specified number of zeros?

I have an array with 3 sections of positive values with zeros spread throughout and large sections of zeros in between the three sections (eg. [1,2,0,0,3,4,0,5,6,7,8,9,0,0,0,0,0,0,0,0,0,0,0,0,0,11,12,13,0,14,0,0,15,16,17,0,0,0,18,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,22,23,24,25,26,0,0,27,0,28,29]). Note: This isn't my actual array.
I want to extract only the first non-zero values from these three sections (eg 1,11,21 in array above) but can't figure out how to. I've tried messing around with if/or statements but can't get anything useful.

3 Comments

I see you want to ignore short runs of 0s, like 1 or 2. What is the min size of the large zero runs? How do I know when the run of zeros is a "large" run? Should we just take the 3 longest runs? Does the vector ever start with a long run of zeros?
How many consecutive zeros are needed before we can consider it the end of a section?
For the example array here, I would say minimum 4, but for my actual array probably 20.

Sign in to comment.

 Accepted Answer

Try this if you have the Image Processing Toolbox:
v = [1,2,0,0,3,4,0,5,6,7,8,9,0,0,0,0,0,0,0,0,0,0,0,0,0,11,12,13,0,14,0,0,15,16,17,0,0,0,18,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,22,23,24,25,26,0,0,27,0,28,29];
% Get a logical comparison to find non-zero elements.
vb = v ~= 0;
% Get rid of runs of 3 elements or less.
minRunLength = 4;
vb = ~bwareaopen(~vb, minRunLength);
% Find starting indexes of non-zeros after long runs of zeros.
indexes = [1, 1 + strfind(vb, [0, 1])]
indexes = 1×3
1 26 60
% OK, they're found. Now let's print them out to the command window.
v(indexes)
ans = 1×3
1 11 21

1 Comment

Thank you so much! It actually took a minRunLength of about 100 but I got my three sections' starts

Sign in to comment.

More Answers (2)

Using this FEX download,
x=[1,2,0,0,3,4,0,5,6,7,8,9,0,0,0,0,0,0,0,0,0,0,0,0,0,11,12,13,0,14,0,0,15,16,17,0,0,0,18,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,22,23,24,25,26,0,0,27,0,28,29];
numzeros=5; %number of consecutive zeros constituting a section divider
[starts,stops,runlengths]=groupLims(groupTrue(~x),1);
idx=[1,stops(runlengths>numzeros)+1];
out=x(idx)
out =
1 11 21

3 Comments

Thanks Matt! This worked great but I accepted Image Analyst's answer so I don't have to have extra function files
Sure, but be aware that you do require additional toolboxes (Image Processing) for that answer to work.

Sign in to comment.

Basic for-loop programing
x=[1,2,0,0,3,4,0,5,6,7,8,9,0,0,0,0,0,0,0,0,0,0,0,0,0,11,12,13,0,14,0,0,15,16,17,0,0,0,18,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,22,23,24,25,26,0,0,27,0,28,29]
x = 1×71
1 2 0 0 3 4 0 5 6 7 8 9 0 0 0 0 0 0 0 0 0 0 0 0 0 11 12 13 0 14
k = 4; % number of 0s from which the sequence is considered as true sequence
j = [];
c = Inf;
for i=1:length(x)
if x(i) ~= 0
if c >= k
j(end+1) = i;
end
c = 0;
else
c = c + 1;
end
end
j
j = 1×3
1 26 60
x(j)
ans = 1×3
1 11 21

Categories

Products

Release

R2021b

Community Treasure Hunt

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

Start Hunting!