# How to find first nonzero element/first '1' per row and set other elements to zero without loops in 3D Matrix

10 visualizzazioni (ultimi 30 giorni)
Tim il 3 Dic 2013
Commentato: Chang Sun il 6 Dic 2015
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!
##### 0 CommentiMostra -2 commenti meno recentiNascondi -2 commenti meno recenti

Accedi per commentare.

### Risposta accettata

Andrei Bobrov il 3 Dic 2013
Modificato: Andrei Bobrov il 3 Dic 2013
s = size(A);
out = zeros(s);
i2 = s(2) - sum(cumsum(A,2)>0,2) + 1;
[ii,kk] = ndgrid(1:s(1),1:s(3))
idx = [ii(:),i2(:), kk(:)];
idx = num2cell(idx(idx(:,2) <= s(2),:),1);
out(sub2ind(s,idx{:})) = 1;
or
A2 = reshape(permute(A,[2 1 3]),s(2),[]);
s2 = size(A2);
[ii,jj] = find(A2);
[~,k] = unique(jj,'first');
ind = [ii,jj];
o1 = zeros(s2);
o1(sub2ind(s2,ind(k,1),ind(k,2))) = 1;
out = permute(reshape(o1,s(2),[],s(3)),[2 1 3]);
##### 1 CommentoMostra -1 commenti meno recentiNascondi -1 commenti meno recenti
Tim il 3 Dic 2013
That works perfectly, thanks a lot!!

Accedi per commentare.

### Più risposte (2)

Jos (10584) il 3 Dic 2013
Something like this?
% input
A = round(rand(5,6,2))
% engine
isOne = A == 1 ;
B = isOne & cumsum(isOne,2) == 1
##### 4 CommentiMostra 2 commenti meno recentiNascondi 2 commenti meno recenti
Simon il 3 Dic 2013
Great!
Chang Sun il 6 Dic 2015
so simple!

Accedi per commentare.

Simon il 3 Dic 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
##### 0 CommentiMostra -2 commenti meno recentiNascondi -2 commenti meno recenti

Accedi per commentare.

### Categorie

Scopri di più su Matrix Indexing in Help Center e File Exchange

### Community Treasure Hunt

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

Start Hunting!

Translated by