Sum Numbers Excluding Zeros
15 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
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
0 commentaires
Réponse acceptée
Jon
le 12 Avr 2019
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
Plus de réponses (1)
Stephen23
le 12 Avr 2019
>> x = [0,0,0,1,0,2,2,3,4,0,0,0,0,7,8,2,2,0,3,0];
>> y = cumsum(x==0 | [true,x(1:end-1)==0]);
>> z = accumarray(y(:),x(:))
z =
0
0
0
1
0
11
0
0
0
0
19
0
3
0
3 commentaires
madhan ravi
le 13 Avr 2019
+1 for both the solutions, Jonathan I highly appreciate your effort too, the solution proposed by you was innovative.
Voir également
Catégories
En savoir plus sur Annotations dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!