2016-11-15 64 views
1

我有3D邏輯陣列,例如:沿第三維度3D邏輯陣列用Matlab「查找」僅

A = randi([0 1],x,y,z); 

其中x,y,z是整數。

有沒有辦法找到沿着第三維「Z」第一個真正的價值,對於每一個(X,Y)?

我能做到這一點在這樣一個循環:

B = zeros(x,y); 

for ix = 1:x 
    for iy = 1:y 
     B(ix,iy) = find(A(ix,iy,:),1,'first'); 
    end 
end 

有數組操作,這將讓我做它沒有一個循環?

回答

1

不是一個非常簡單的一個。

這是因爲沿着第三維的任何地方都可能不存在 a true

順便說一句,你正在做什麼可能會導致極其很難找到錯誤。如果是有什麼地方沒有真正的價值的情況下,find將返回空矩陣([])。而且,在MATLAB的東西分配一個空矩陣將刪除該元素的數組你分配給。

含義:

  1. B(ix,iy)將被刪除
  2. 中元素的個數您B將1
  3. 收縮所有後續結果將被分配到錯誤的位置在B
  4. 當你「VE達到A結束時(並因此現在索引的B邊界之外),MATLAB將自動增長陣列B以適應ÿ我們的任務。

你不會更聰明,但所有的結果都是毫無意義的垃圾。

幸運的是,MATLAB拋出一個警告,如果你正在做的是在陣列上具有尺寸大於1,BUT,如果您使用上矢量相同的技術(例如,B是矢量) ,MATLAB不會提醒你。

所以,在最起碼,做一次檢查:

for ix = 1:x 
    for iy = 1:y 
     if any(A(ix,iy,:)) 
      B(ix,iy) = find(A(ix,iy,:), 1, 'first'); 
     end 
    end 
end 

還要注意的是any可以採取第二個參數指定爲「any」在尺寸,這意味着

any(A,3) 

將返回一個x×y陣列邏輯值的,含有true如果在沿其第三維A一個true,並false否則。這可能有助於防止必須明確計算索引(通常,如果更改範例,它們並不真正需要)。現在

,說了這麼多,你可以使用

[~, B] = max(A ~= 0, [], 3); 

,但你仍然必須做全零檢查:

B(~any(A, 3)) = 0; 

我會說,循環用支票只是所以更直觀,它會有我的偏好。然而,max技術的速度要快7倍,所以當正確記錄時(可能將循環作爲註釋的一部分,以及隨附的單元測試),那麼爲什麼不呢。