2016-11-09 65 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').'