[英]How to vectorize conditional triple nested for loop - MATLAB
我有兩個 3D arrays:
形狀是240 x 121 x 10958陣列
面積是240 x 1 x 10958陣列
arrays 的值是 double 類型。 在沒有相關數據的情況下,兩者都將 NaN 作為填充值。
對於形狀數組的每個 [240 x 121] 頁,有幾個元素填充相同的數字。 例如,會有一個 1 的塊,一個 2 的塊,等等。對於區域數組的每個對應頁面,都有一個 240 行長的數值列。 我需要做的是逐步 go 穿過形狀數組的每一頁(沿第 3 個,10958 長軸移動),並用填充區域數組中匹配數字行的數字替換該頁面中的每個編號元素。
例如,如果我正在查看shape(:,:,500)
,我想將該頁面上的所有 8 替換為area(8,1,500)
。 我需要對數字 1 到 20 執行此操作,並且我需要對數組的所有 10958 頁執行此操作。
如果我提取一個頁面並且只替換一個數字,我可以讓它工作:
shapetest = shape(:,:,500);
shapetest(shapetest==8)=area(8,1,500);
這正是我需要的一頁和一個數字。 使用 for 循環遍歷數字 1-20 似乎不是問題,但我找不到對原始 3D 數組的所有頁面執行此操作的矢量化方法。 事實上,如果不像上面那樣將該頁面提取為自己的矩陣,我什至無法讓它在單個頁面上工作。 我嘗試過這樣的事情無濟於事:
shape(shape(:,:,500)==8)=area(8,1,500);
如果我不能在一頁上完成,我會更加迷失如何一次完成所有內容。 但是我對 MATLAB 沒有經驗,我想我只是不知道正確的語法。
相反,我最終使用了一個單元格數組和以下非常低效的嵌套 for 循環:
MyCell=num2cell(shape,[2 1]);
shapetest3=reshape(MyCell,1,10958);
for w=1:numel(shapetest3)
test_result{1,w}=zeros(121,240)*NaN;
end
for k=1:10958
for i=1:29040 % 121 x 240
for n=1:20
if shapetest3{1,k}(i)==n
test_result{1,k}(i)=area(n,1,k);
end
end
end
end
這樣就完成了工作,我可以輕松地將其轉回數組,但速度很慢,我相信有更好的矢量化方式。 我將不勝感激任何幫助或提示。 提前致謝。
為了向量化映射操作,我們可以使用shape
作為area
的索引。 但是因為每個平面的映射是不同的,我們需要遍歷平面來完成這個。 簡而言之,它看起來像這樣:
test_result = zeros(size(shape)); % pre-allocate output
for k=1:size(area,3) % loop over planes
lut = area(:,1,k);
test_result(:,:,k) = lut(shape(:,:,k));
end
以上僅適用於shape
僅包含 [1,N] 范圍內的 integer 值,其中N = size(area,1)
。 也就是說,對於shape
中的其他值,我們將進行錯誤的索引。 我們需要修復shape
以避免這種情況。 這里的問題是,我們要如何處理這些超出范圍的值?
例如,准備shape
來處理 NaN 值:
code = size(area,1) + 1; % this is an unused code word
shape(isnan(shape)) = code;
area(code,1,:) = NaN;
這會將shape
中的所有 NaN 值替換為值code
,該值比我們映射的任何 code 值大一。 然后,我們擴展area
以獲得另一個值,即輸入code
的值。 我們在此處填寫的值是 output test_result
將具有的值,其中shape
為 NaN。 在這種情況下,我們寫 NaN,這樣輸入中的 NaN 映射到 output 中的 NaN。
可以使用低於 0 和高於 240 的值( shape(shape<1 | shape>240) = code
)或使用非整數值( shape(mod(shape,1)~=0) = code
)進行類似的操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.