How to find first nonzero element/first '1' per row and set other elements to zero without loops in 3D Matrix
    13 visualizzazioni (ultimi 30 giorni)
  
       Mostra commenti meno recenti
    
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 Commenti
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]);
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 Commenti
  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 Commenti
Vedere anche
Categorie
				Scopri di più su Resizing and Reshaping Matrices 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!




