13 Stimmen

Wie kann ich eine 3-D-Matrix mit einer 2-D-Maske in MATLAB indizieren?

Angenommen, ich habe D, eine X-mal-Y-mal-Z-Datenmatrix. Ich habe auch M, eine X-mal-Y "Maskierungs"-Matrix. Mein Ziel ist es, die Elemente (Xi,Yi,:) in D auf NaN zu setzen, wenn (Xi,Yi) in M falsch ist.

Gibt es eine Möglichkeit, dies in einer Schleife zu vermeiden? Ich habe versucht, mit ind2sub aber das schlägt fehl:

M = logical(round(rand(3,3))); % mask
D = randn(3,3,2); % data

% try getting x,y pairs of elements to be masked
[x,y] = ind2sub(size(M),find(M == 0));
D_masked = D;
D_masked(x,y,:) = NaN; % does not work!

% do it the old-fashioned way
D_masked = D;
for iX = 1:size(M,1)
    for iY = 1:size(M,2)
        if ~M(iX,iY), D_masked(iX,iY,:) = NaN; end
    end
end

Ich vermute, ich übersehe hier etwas Offensichtliches. (:

13voto

gnovice Punkte 124264

Sie können dies tun, indem Sie Ihre logische Maske replizieren M über die dritte Dimension mit REPMAT so dass es die gleiche Größe hat wie D . Dann, Index weg:

D_masked = D;
D_masked(repmat(~M,[1 1 size(D,3)])) = NaN;

Wenn die Replikation der Maskenmatrix nicht erwünscht ist, gibt es eine andere Alternative. Sie können zunächst eine Reihe von linearen Indizes finden, für die M gleich 0 ist, dann diese Menge replizieren size(D,3) mal, dann verschieben Sie jeden Satz von Indizes um ein Vielfaches von numel(M) indiziert also einen anderen Teil von D in der dritten Dimension. Ich möchte dies anhand folgender Beispiele veranschaulichen BSXFUN :

D_masked = D;
index = bsxfun(@plus,find(~M),(0:(size(D,3)-1)).*numel(M));
D_masked(index) = NaN;

0voto

Daniel Punkte 36242

Reshape ist grundsätzlich kostenlos Sie können es hier für eine effiziente Lösung verwenden, indem Sie das Ganze auf ein 2d-Problem reduzieren.

sz=size(D);
D=reshape(D,[],sz(3)); %reshape to 2d
D(isnan(M(:)),:)=nan; %perform the operation on the 2d matrix
D=reshape(D,sz); %reshape back to 3d

-3voto

c-urchin Punkte 4194

Mein Matlab ist ein bisschen eingerostet, aber ich denke, dass die logische Indizierung funktionieren sollte:

D_masked = D;
D_masked[ M ] = NaN;

(die wahrscheinlich in einer einzigen Aussage mit einem bedingten Ausdruck auf dem rechten Teil zusammengefasst werden können...)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X