How to find first nonzero element/first '1' per row and set other elements to zero without loops in 3D Matrix
Show older comments
I've a Matrix f.ex. like
A=[0,1,1,0; 1,0,0,1;0,0,0,1;0,1,1,1]; A =
0 1 1 0
1 0 0 1
0 0 0 1
0 1 1 1
only in 3D. So for example a Matrix like this only 100times (size(A)=4 x 4 x 100). Of course different shape/form of the '1s' and '0s'.
I want to as a result only the first '1' of each row and all other elements or further "1" to zero. The result should be:
B=[0,1,0,0;1,0,0,0;0,0,0,1;0,1,0,0];
B =
0 1 0 0
1 0 0 0
0 0 0 1
0 1 0 0
again, a hundred times. So the Result would be again size(B)= 4 x 4x 100.
If it was a 2D-matrix I'd use this: [Y,I] = max(A, [], 2); B = zeros(size(A)); B(sub2ind(size(A), 1:length(I), I')) = Y;
But that doesn't work for a 3Dim-Matrix...And I don't want to use for loop. Thanks!
Accepted Answer
More Answers (2)
Jos (10584)
on 3 Dec 2013
Something like this?
% input
A = round(rand(5,6,2))
% engine
isOne = A == 1 ;
B = isOne & cumsum(isOne,2) == 1
4 Comments
Andrei Bobrov
on 3 Dec 2013
+1
Tim
on 3 Dec 2013
Simon
on 3 Dec 2013
Great!
Chang Sun
on 6 Dec 2015
so simple!
Simon
on 3 Dec 2013
Hi!
Why don't you want loops? It is the easiest way. Try this:
ix = 1:size(A, 1);
% loop over al columns
for col = 1:size(A, 2)-1;
% find line with '1' in current column
ind = (A(ix, col) == 1);
% set rest of found lines to '0'
A(ix(ind), col+1:end) = 0;
% delete found lines from index -> no check needed anymore!
ix = ix(~ind);
% if we checked all lines we have finished -> break out of loop
if isempty(ix)
break
end
end
Categories
Find more on Resizing and Reshaping Matrices in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!