我具有矩陣說更改矩陣的多個元素(的已知座標),而不for循環
Z = [1 2 3;
4 5 6;
7 8 9]
我必須改變其值,在位置(2,2)和說(3,1 ),某些指定的值。我有兩個矩陣rowNos
和colNos
含有這些位置:
rowNos = [2, 3]
colNos = [2, 1]
比方說,我想在這些位置來改變元素的值設置爲0
我怎麼能做到這一點,而不使用循環?
我具有矩陣說更改矩陣的多個元素(的已知座標),而不for循環
Z = [1 2 3;
4 5 6;
7 8 9]
我必須改變其值,在位置(2,2)和說(3,1 ),某些指定的值。我有兩個矩陣rowNos
和colNos
含有這些位置:
rowNos = [2, 3]
colNos = [2, 1]
比方說,我想在這些位置來改變元素的值設置爲0
我怎麼能做到這一點,而不使用循環?
使用sub2ind,它會你的分項指數轉換爲線性指標,這是一個數字指向矩陣中的一個確切點(more info)。
Z = [ 1 2 3 ; 4 5 6 ; 7 8 9];
rowNos = [2, 3];
colNos = [2, 1];
lin_idcs = sub2ind(size(Z), rowNos, colNos)
如果你想在一個特定的行和列(在更高維度即元素)的所有元素進行操作,也可以使用線性索引解決這些問題。它才成爲計算它們的一些技巧:
Z = reshape(1:4*4*3,[4 4 3]);
rowNos = [2, 3];
colNos = [2, 1];
siz = size(Z);
lin_idcs = sub2ind(siz, rowNos, colNos,ones(size(rowNos))); % just the first element of the remaining dimensions
lin_idcs_all = bsxfun(@plus,lin_idcs',prod(siz(1:2))*(0:prod(siz(3:end))-1)); % all of them
lin_idcs_all = lin_idcs_all(:);
Z(lin_idcs_all) = 0;
實驗了一下與sub2ind,並通過我的代碼一步一步的去了解它。
它會一直更容易,如果這是你想要採取的所有元素關閉第一個維度,那麼你也可以使用冒號運算:
Z = reshape(1:3*4*4,[3 4 4]);
rowNos = [2, 3];
colNos = [2, 1];
siz = size(Z);
lin_idcs = sub2ind(siz(2:end),rowNos,colNos);
Z(:,lin_idcs) = 0;
使用sub2ind
具有多個條目的行和列
Z(sub2ind(size(Z), rowNos, colNos))=0
例:
Z = [1 2 3;
4 5 6;
7 8 9];
rowNos = [2, 3];
colNos = [2, 1];
Z(sub2ind(size(Z), rowNos, colNos))=0
Z =
1 2 3
4 0 6
0 8 9
非常感謝@gevang。 還有一個小問題。我如何將它擴展到三維矩陣?如果Z被稱爲3x3x3矩陣,該怎麼辦? (我實際上想要改變圖像的RGB值,所以我已經這樣簡化了它) 那麼如何有3個值與每個位置相關聯,我想用3個其他指定值來改變它們。我怎麼做? – shahensha
沿着與@Gunther Struyf相同的線條,我也建議用於在第三維上循環的3維矩陣(即RGB-圖像),其是乾淨的並且不費錢(即使對於巨大的二維維度),即'c = [ - 1; -2; -3];對於i = 1:3,Z(sub2ind(size(Z),rowNos,colNos,repmat(i,1,size(rowNos,2))))= c(i)結束' – gevang
你想做到這一點
z(rowNos, colNos)
但你不能 - MATLAB做了指數的笛卡爾乘積。您可以這樣做:
idx=(colNos-1)*size(z, 1)+rowNos;
z(idx)=0
展平z矩陣並通過線性索引訪問它,該索引是rowNos和colNos的組合。請記住,MATLAB通過列平坦化矩陣(基於列的矩陣存儲)。
這實際上是'sub2ind'的作用,但是這隻適用於2d矩陣當然這裏有訣竅,但對於連續性來說,使用sub2ind更容易) –
對於更高維度,您可以執行相同的技巧,這不是真正的技巧,而是sub2ind的功能。但其確實需要知道MATLAB數據結構。 sub2ind將你從中解脫出來,但我很想知道事情是如何運作的。 – angainor
(nofi),所以你也可以使用'sum(x)/ length(x)'來計算矢量的均值:p –
爲什麼你想避免在這裏的循環? –
@MarcusRiemer,因爲我打算在大型圖像上應用這個東西。事實上是巨大的。我感覺,Vectorization將幫助我的代碼比普通的循環更快地運行。 – shahensha