2014-02-10 148 views
3

如何打開一個矩陣:什麼是在MATLAB中展開矩陣的最快方法?

[ 0.12 0.23 0.34 ; 
    0.45 0.56 0.67 ; 
    0.78 0.89 0.90 ] 

與一幫行的「座標」矩陣?

[ 1 1 0.12 ; 
    1 2 0.23 ; 
    1 3 0.34 ; 
    2 1 0.45 ; 
    2 2 0.56 ; 
    2 3 0.67 ; 
    3 1 0.78 ; 
    3 2 0.89 ; 
    3 3 0.90 ] 

(行的排列是無關緊要的,只在乎數據是在這個結構中)

現在我使用for循環但那要花費很長的時間。

回答

9

這裏是一個選項使用ind2sub

mat= [ 0.12 0.23 0.34 ; 
    0.45 0.56 0.67 ; 
    0.78 0.89 0.90 ] ; 

[I,J] = ind2sub(size(mat), 1:numel(mat)); 
r=[I', J', mat(:)] 

r = 

    1.0000 1.0000 0.1200 
    2.0000 1.0000 0.4500 
    3.0000 1.0000 0.7800 
    1.0000 2.0000 0.2300 
    2.0000 2.0000 0.5600 
    3.0000 2.0000 0.8900 
    1.0000 3.0000 0.3400 
    2.0000 3.0000 0.6700 
    3.0000 3.0000 0.9000 

注意指數相比你的例子是顛倒了。

+1

可替換地,丟棄一組中間體的爲了整潔,'ind2sub(size(A),1:numel(A))' – Notlikethat

+0

他說行的排列是不相關的,所以這應該是一樣的。這樣的行仍然是相同的。 (引用你的說明btw) – scenia

6
A = [ .12 .23 .34 ; 
     .45 .56 .67 ; 
     .78 .89 .90 ]; 

[ii jj] = meshgrid(1:size(A,1),1:size(A,2)); 
B = A.'; 
R = [ii(:) jj(:) B(:)]; 

如果不(根據您的編輯)介意不同的順序,你可以更容易地做到這一點:

[ii jj] = ndgrid(1:size(A,1),1:size(A,2)); 
R = [ii(:) jj(:) A(:)]; 
5

除了與meshgrid產生的行/列的索引,您可以使用find三個輸出如下:

[II,JJ,AA]= find(A.'); %' note the transpose since you want to read across 
M = [JJ II AA] 
M = 
      1   1   0.12 
      1   2   0.23 
      1   3   0.34 
      2   1   0.45 
      2   2   0.56 
      2   3   0.67 
      3   1   0.78 
      3   2   0.89 
      3   3   0.9 

應用受到限制,因爲零迷路。討厭的,但正確的解決方法(感謝user664303):

B = A.'; v = B == 0; %' transpose to read across, otherwise work directly with A 
[II, JJ, AA] = find(B + v); 
M = [JJ II AA-v(:)]; 

不用說了,我會建議其他的解決方案之一。 :)特別是,ndgrid是獲得行,col inds的最自然的解決方案。

+0

哦,但零...嗯 – chappjc

+0

一個不是非常優雅的解決方案,以覆蓋零的情況:添加,然後減去'min(A(:))+ 1' –

+1

錯誤修復,並沒有損失的準確性:'B = A. v = B == 0; [II,JJ,AA] = find(B + v); M = [JJ II AA-v(:)];' – user664303

1

我發現ndgrid是最自然的解決方案,但這裏有一個有趣的方式來與奇數夫婦的kronrepmat做手工:

M = [kron(1:size(A,2),ones(1,size(A,1))).' ... %' row indexes 
    repmat((1:size(A,1))',size(A,2),1) ...  %' col indexes 
    reshape(A.',[],1)]       %' matrix values, read across 

簡單調整往下看了,因爲是在MATLAB自然:

M = [repmat((1:size(A,1))',size(A,2),1) ...  %' row indexes (still) 
    kron(1:size(A,2),ones(1,size(A,1))).' ... %' column indexes 
    A(:)]          % matrix values, read down 

(也因爲我的第一個答案是可恥的hackish。)


我還發現kron是一個很好的工具,可以一次複製每個元素,而不是一次完成整個數組,如repmat所做的那樣。例如:

>> 1:size(A,2) 
ans = 
    1  2  3 
>> kron(1:size(A,2),ones(1,size(A,1))) 
ans = 
    1  1  1  2  2  2  3  3  3 

採取這種有點進一步,我們可以生成一個稱爲repel複製的陣列的元素,而不是整個陣列的新功能:

>> repel = @(x,m,n) kron(x,ones(m,n)); 
>> repel(1:4,1,2) 
ans = 
    1  1  2  2  3  3  4  4 
>> repel(1:3,2,2) 
ans = 
    1  1  2  2  3  3 
    1  1  2  2  3  3 
相關問題