2010-08-04 45 views
12

假設我有一個X-Y-Z-Z數據矩陣D.我也有M,一個X-by-Y「掩蔽」矩陣。我的目標是當M中的(Xi,Yi)爲假時,將D中的元素(Xi,Yi,:)設置爲NaN。如何在MATLAB中使用2-D蒙版索引3-D矩陣?

有什麼辦法可以避免在循環中做到這一點?我試着用ind2sub,但失敗:

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 

我懷疑我缺少明顯的東西在這裏。 (:

回答

12

您可以通過在使用REPMAT所以它是大小相同的D第三維複製你的邏輯掩碼M這樣做,那麼,指數走:

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

如果不希望複製掩模矩陣,還有另一種方法。您可以首先找到一組線性索引,其中M等於0,然後複製該集合size(D,3)次,然後將每組索引移動numel(M)的倍數,因此它在第三維中索引D的不同部分。我會用BSXFUN這裏說明這一點:

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

啊,當然,這是有效的。對於D和M的巨大尺寸,雖然它可能仍然是可取的而不必複製它... – 2010-08-04 16:45:53

+0

@Matt:由於'M'是一個邏輯矩陣,它只使用每個元素1個字節,所以複製它將不會使用幾乎與複製雙打矩陣一樣多。實際上,複製版本的「M」只會佔用D的總內存的1/8。 – gnovice 2010-08-04 16:50:09

+2

@Matt:爲了完整起見,我添加了另一個避免複製'M'的解決方案。如果在一個非常大的矩陣「M」中只有幾個零值,從內存使用的角度來看,這種新的解決方案可能更爲理想。 – gnovice 2010-08-04 17:09:44

-2

我的Matlab是有點生疏,但我認爲邏輯索引應該工作:

D_masked = D; 
D_masked[ M ] = NaN; 

(這可能可以用在RHS條件表達式組合成一個語句...)

+1

啊,我應該已經包括在「東西我試過」 :-)如果你這樣做,你只能掩蓋第一Z尺寸,所以d(:,: ,1)將應用掩模但不包括D(:,:,2)。還是)感謝你的建議! – 2010-08-04 16:27:33