2016-11-09 80 views
4

列我有一個2D矩陣,其中列的№總是3的倍數(例如250×27) - 由於結果(A,B,CA,B,CA,B,C,等等)的重複組織。我希望重塑這個矩陣以創建一個有3列的新矩陣 - 每個矩陣包含每種類型的彙總數據(A,B,C)(例如2250×3)。摺疊矩陣成

因此,在250×27的矩陣中,列1,4,7,10,13,16,19,22,25中的所有數據將被合併以形成所得到的重整矩陣的第一列。

生成的整形矩陣中的第二列將包含列2,5,8,11,14,17,20,23,26中的所有數據 - 依此類推。

有沒有一種簡單的方法可以在MATLAB中做到這一點?我只知道如何使用reshape如果我想合併的列是相鄰(1,2,3,4,5,6),而不是不相鄰(1,4,7,10,13,16)等

回答

3

無恥從@Divakar

B = reshape(permute(reshape(A,size(A,1),3,[]), [1,3,2]), [], 3); 
1

A是你的矩陣。您可以將每個第三列保存在一個矩陣中,例如: (請注意,您不必將它們分別保存爲矩陣,但它使此示例更易於閱讀)。

A = rand(27); %as test 
B = A(:,1:3:end); 
C = A(:,2:3:end); 
D = A(:,3:3:end); 

然後使用重塑:

B = reshape(B,[],1); 
C = reshape(C,[],1); 
D = reshape(D,[],1); 

最後把它放在一起:

A = [B C D]; 
+0

我想通過跳過這個可以使它變得更緊湊中間塊,並在最後一個塊使用B(:)',但總體而言,這似乎是正確的路要走。 –

2

你可以只是把每列集作爲一個單一的項目,並做好三重塑在一起。這應該做的伎倆:

[保存在您的MATLAB文件夾「reshape3.m」文件來調用它作爲函數]

function out = reshape3(in) 
    [~,C]=size(in); % determine number of columns 
    if mod(C,3) ~=0 
     error('ERROR: Number of rows must be a multiple of 3') 
    end 

    R_out=numel(in)/3; % number of rows in output 

    % Reshape columns 1,4,7 together as new column 1, column 2,5,8 as new col 2 and so on 
    out=[reshape(in(:,1:3:end),R_out,1), ... 
     reshape(in(:,2:3:end),R_out,1), ... 
     reshape(in(:,3:3:end),R_out,1)]; 
end 
-2

嘗試Matlab function mat2cell,我覺得這種形式是允許的。

X is the "start matrix"  
C = mat2cell(X, [n], [3, 3, 3]); %n is the number of rows, repeat "3" as many times as you nedd 

%extract every matrix 
C1 = C{1,1}; %first group of 3 columns 
C2 = C{1,2}; %second group of 3 columns 
%repeat for all your groups 

%join the matrix with vertcat 
Cnew = vertcat(C1,C2,C3); %join as many matrix n-by-3 as you have 
+2

不起作用(最明顯的提示是C1 == C2),使用單元格從一個矩陣形狀到另一個矩陣形狀通常是一個壞主意,因爲這是非常低效的。 –

+0

@DennisJaheruddin C1 = C2顯然是我的失誤指數(更新),謝謝。爲什麼Matlab內置函數被認爲效率很低? – marcoresk

+0

內置功能一般都很好。但是單元格比矩陣是一個更通用的數據類型。因此,通常在矩陣上操作而不是將其轉換爲單元,在單元上操作並將其轉換爲矩陣更有效。 - 對於小問題,效率可能不是問題,但在這種情況下,我仍然會爭辯說,除非有令人信服的理由,否則堅持矩陣是代碼清晰度的最佳實踐。 –

1

允許假設有一個3×6矩陣A

A = [1 2 3 4 5 6;6 5 4 3 2 1;2 3 4 5 6 7] 
A = 

    1  2  3  4  5  6 
    6  5  4  3  2  1 
    2  3  4  5  6  7 

您提取矩陣的大小

b =size(A) 

然後提取每個第三列的單個行

c1 = A((1:b(1)),[1:3:b(2)]) 
c2 = A((1:b(1)),[2:3:b(2)]) 
c3 = A((1:b(1)),[3:3:b(2)]) 

並把它們放在一個矩陣

A_result = [c1(:) c2(:) c3(:)] 

A_result = 

    1  2  3 
    6  5  4 
    2  3  4 
    4  5  6 
    3  2  1 
    5  6  7 
+1

儘管它有效,但它似乎沒有增加太多的現有答案和評論。 –

+0

@ DennisJaheruddin當我看到這個問題時沒有答案,所以只是分享了另一種做法 – Umar

0

這裏是我的2分鐘對其​​採取:

rv = @(x) x(:); 
ind = 1:3:size(A,2); 
B = [rv(A(:,ind)) rv(A(:,ind+1)) rv(A(:,ind+2))]; 

節省一些醜陋reshape S,可能會有點慢,但。

1

我的2美分:

nRows = size(matrix, 1); 
nBlocks = size(matrix, 2)/3; 
matrix = reshape(matrix, [nRows 3 nBlocks]); 
matrix = permute(matrix, [1 3 2]); 
matrix = reshape(matrix, [nRows * nBlocks 1 3]); 
matrix = reshape(matrix(:), [nRows * nBlocks 3]); 
0

如果你有圖像處理工具箱im2col是一個非常方便的解決方案:

out = im2col(A,[1 4], 'distinct').'