2017-12-12 1 views
2

Wenn angenommen, ein 3x3x3-Array, wie ersetzt man das gesamte dim3, wenn eine Bedingung erfüllt ist? Whith gegebenen ArrayErsetzen Sie dim3 in Matlab-Array

A = [1 2 3; 4 1 6; 7 8 1]; 
A(:, :, 2) = [1 2 3; 4 2 6; 7 8 2] 
A(:, :, 3) = [1 2 3; 4 3 6; 7 8 3] 

In diesem einfachen Fall gibt es zwei dim3s [1 2 3] enthält, auf A(2,2,:) und A(3,3,:). Wie könnte ich sie zum Beispiel durch [10 10 10] ersetzen. Dies scheint sehr einfach, aber ich kann einfach nicht meinen Kopf drumherum ...

Edit: Ich azidently übersimplified die Probelem, der Ersatz Vektor sollte eher etwas wie [11 12 13] finden der (X, Y) -Index ist nicht das eigentliche Problem.

I für eine saubere und speichereffiziente Weise suchen zu ersetzen A(2,2,:) und A(3,3,:) mit [11 12 13] Erhalt des Ausgang: A (:,:, 1) =

 1  2  3 
    4 11  6 
    7  8 11 


A(:,:,2) = 

    1  2  3 
    4 12  6 
    7  8 12 


A(:,:,3) = 

    1  2  3 
    4 13  6 
    7  8 13 

Curcial in diesem Fall , ist, dass ich nicht weiß, wie viele ements in der realen Welt Problem ersetzt werden müssen ...

+0

Der Ersatz ist nur 'A (2,2 ,:) = 10; 'oder' A (3,3, :) = 10; 'Fragen Sie auch, wie Sie herausfinden können, ob diese Bedingung existiert? –

+0

Ich verstehe nicht, was Sie wollen. Was sind die Eingaben und die gewünschte Ausgabe (in Ihrem Beispiel)? –

Antwort

1

Nur einige logische Indizierung (Matlab 2016b und später):

target = [1 2 3]; % the vector you want to find 
replacement = [11 12 13]; % the vector you want to replace it with 

% find the 2d indexes where the target is found 
idx = all(A == permute(target,[1 3 2]),3); 
% replace found indexes with replacement vector 
A(logical(idx.*ones(1,1,size(A,3)))) = repelem(replacement,1,nnz(idx)); 

Das Gleiche gilt für Matlab pre 2016b:

idx = all(bsxfun(@eq,A,permute(target,[1 3 2])),3); 
A(logical(bsxfun(@times,idx,ones(1,1,size(A,3))))) = repelem(replacement,1,nnz(idx)); 
+0

Vielen Dank! Interessanterweise ist es nicht schneller als die Verison mit der Schleife. Zumindest für ein '2769x2694x3 uint8' – mhwh

0

Ersetzen der Elemente entlang der dritten Dimension ist nur eine Aufgabe.

A(2,2,:) = 10; 
A(:,:,1) = 
    1  2  3 
    4 10  6 
    7  8  1  
A(:,:,2) = 
    1  2  3 
    4 10  6 
    7  8  2 
A(:,:,3) = 
    1  2  3 
    4 10  6 
    7  8  3 

Wenn Sie versuchen, zu identifizieren, wo Sie das 1,2,3 Muster entlang der dritten Dimension haben könnten Sie so etwas tun:

idx= A(:,:,1) == 1 & A(:,:,2) ==2 & A(:,:,3) == 3; 
idx= repmat(idx,1,1,3); 
A(idx) = 10; 

was zur Folge hat:

A(:,:,1) = 
    1  2  3 
    4 10  6 
    7  8 10 
A(:,:,2) = 
    1  2  3 
    4 10  6 
    7  8 10 
A(:,:,3) = 
    1  2  3 
    4 10  6 
    7  8 10 
+0

Prost Das hilft sicherlich - ich denke, dass ich einen Fehler mit meiner Frage gemacht habe, indem ich '[10 10 10]' als Ersatz gebe - ich will tatsächlich einen Vektor wie '[10 11 12]' setzen, damit der einfache Index nicht funktioniert dieser Fall ... – mhwh

0

Ich habe irgendwie eine Lösung basierend auf 'Aero Engys vorherigem Post ausgearbeitet. Es ist jedoch sehr hässlich, da es Zuweisungen in einer Schleife erfordert - hat jemand eine Idee für eine vektorisierte Version?

A = [1 2 3; 4 1 6; 7 8 1]; 
A(:, :, 2) = [1 2 3; 4 2 6; 7 8 2]; 
A(:, :, 3) = [1 2 3; 4 3 6; 7 8 3]; 

Target = [1 2 3]; 
Replacement = [11 12 13]; 

idx = find(A(:,:,1) == Target(1) & A(:,:,2) == Target(2) & A(:,:,3) == Target(3)); 
[x, y, ~] = ind2sub(size(A), idx); 

for i = 1:length(x) 
A(x(i), y(i), 1) = Replacement(1); 
A(x(i), y(i), 2) = Replacement(2); 
A(x(i), y(i), 3) = Replacement(3); 
end