MATLAB: Sum Numbers Excluding Zeros

sum

I have an array like this [2 2 3 4 0 0 0 0 7 8 2 2]. Please i want to add the numbers excluding the zeros to have something like this[11 0 0 0 0 19] Please is there a way I can do it. Thanks

Best Answer

The following code should do what you want. There may be some way to do this more elegantly, but I think this works and should be fairly efficient. I haven't thoroughly tested it for all edge cases. If this works for you it would be good to make it into a function that just took the input vector and returned the condensed output.
% code to condense non-zero elements in a vector into single values
% for example x = [0 1 0 2 2 3 4 0 0 0 0 7 8 2 2 0 3 0] should give
% xCond = [0 1 0 11 0 0 0 0 19 0 3 0]
x = [0 1 0 2 2 3 4 0 0 0 0 7 8 2 2 0 3 0];
% pad start and end of original vector with zero to allow detection of
% transitions to at ends of vector
xPad = [0 x 0];
% find locations where we transition from zero to non-zero elements
startIdx = find(xPad(1:end-1) == 0 & xPad(2:end)~=0);
% find locations where we transition from non-zero to zero elements
stopIdx = find(xPad(2:end)==0 & xPad(1:end-1)~=0)-1;
% find the number of non-zero segments (each pair of start and stop idx
% defines a non-zero segment that must be condensed into a single value
numSegments = length(startIdx); % startIdx and stopIdx are same length
% find the number of zero values
numZeros = sum(x == 0);
% Each pair of start and stop idx defines a non-zero segment that must be
% condensed into a single value. The length of the condensed vector will be
% the number of non-zero segments plus the number of zero elements that are
% left as spacers
% preallocate an appropriately sized vector to hold the condensed vector
xCond = zeros(1,numSegments + numZeros);
% loop through segments computing condensed sums and forming condensed
% vector
idx = startIdx(1); % initial location in the output vector
for k = 1:numSegments
% condense current segment
xCond(idx) = sum(x(startIdx(k):stopIdx(k)));
% increment the count to the next location
if k + 1 <= numSegments % watch for end condition
idx = idx + (startIdx(k+1) - stopIdx(k));
end
end