【问题标题】:MATLAB - re-arrange matrix by vertically concatenating submatricesMATLAB - 通过垂直连接子矩阵重新排列矩阵
【发布时间】:2012-06-09 21:36:01
【问题描述】:

我在执行以下任务时遇到问题: 假设一个 3x6 矩阵:

A =

0.2787    0.2948    0.4635    0.8388    0.0627    0.0435
0.6917    0.1185    0.3660    0.1867    0.2383    0.7577
0.6179    0.7425    0.0448    0.4009    0.9377    0.4821

我想做的是将矩阵分成块,如下所示:

A =

0.2787    0.2948  |  0.4635    0.8388  |  0.0627    0.0435
0.6917    0.1185  |  0.3660    0.1867  |  0.2383    0.7577
0.6179    0.7425  |  0.0448    0.4009  |  0.9377    0.4821

并垂直连接这些块以获得最终结果:

0.2787    0.2948 
0.6917    0.1185  
0.6179    0.7425  
0.4635    0.8388
0.3660    0.1867
0.0448    0.4009
0.0627    0.0435
0.2383    0.7577
0.9377    0.4821

我想如果我能得到这方面的帮助,那么我也许可以 对任意矩阵执行此操作。我可以解决上述问题 使用 for 循环的问题,但我正在寻找矢量化解决方案。

提前致谢! N.

【问题讨论】:

  • 查找reshape
  • 我认为这不仅仅是重塑。我的意思是重塑与其他一些操作相结合......
  • 对于那些感兴趣的人,这里有一个相关的问题:split long 2D matrix into the third dimension
  • @user1438310 是的,我知道。我提到了一个你可能不知道的工具。如果您可能包含有关您尝试过的内容的内容,我就不会提及它。

标签: matlab matrix


【解决方案1】:

没有cell2mat,(仅使用reshapes 和permute)也可以做到这一点,因此速度要快得多!

您需要使用“第三维”。它类似于中描述的内容 split long 2D matrix into the third dimension

这是上述矩阵的解决方案:

A1 = reshape(A, 3, 2, []);  % 3rd dimension is numel(A)/2/3
A2 = permute(A1, [2 1 3]);  % transpose 1st and 2nd dimension
Ans= reshape(A2, 2, [])' ;  % note the transpose

对于这种大小的矩阵,运行时间的差异可以忽略不计。但是,对于一个大矩阵来说,差别不止一个数量级:

A=rand(3, 2*10000);

%% good method

tic
A1 = reshape(A, 3, 2, []); %3rd dimension is numel(A)/2/3
A2 = permute(A1, [2 1 3]);
A3 = reshape(A2, 2, [])' ; %note the transpose'
toc

%% mat2cell method

tic
blkSz = 2;
C = mat2cell(A, size(A,1), blkSz*ones(1,size(A,2)/blkSz));
B3 = cat(1,C{:});
toc

%% make sure the answer is the same:
assert(max(A3(:)-B3(:))==0)

输出:

>> Elapsed time is 0.001202 seconds.
>> Elapsed time is 0.043115 seconds.

【讨论】:

    【解决方案2】:

    通过垂直连接,假设矩阵宽度可以被 3 整除:

    B = [ A(:,1:(size(A,2)/3)); A(:,size(A,2)/3+1:size(A,2)/3*2); A(:,size(A,2)/3*2+1:end) ];
    

    【讨论】:

      【解决方案3】:

      这个怎么样:

      width = 2; 
      m = length(A(:))/width;
      fn = @(i) reshape(A(:, i:width:end), m, 1);
      B = cell2mat(arrayfun(fn, 1:width, 'UniformOutput', false));
      

      只需在 width 变量中指定一次需要多少列。

      【讨论】:

        【解决方案4】:

        这适用于您的矩阵为A 而您想要的是D

        C = mat2cell(A,[3],[2 2 2])
        D = cat(1,C{:})
        

        【讨论】:

          【解决方案5】:

          考虑以下几点:

          A = rand(3,6);
          blkSz = 2;
          
          C = mat2cell(A, size(A,1), blkSz*ones(1,size(A,2)/blkSz));
          C = cat(1,C{:})
          

          这假设size(A,2) 可以被blkSz 整除

          【讨论】:

          • 感谢您的回复,我需要一段时间才能将您的解决方案应用于我的代码,但我会尽快回复您..
          • SO 直到我也发布了我的答案之后才引用。 :)
          • @Amro 我有义务为你的投票投赞成票,被你抢走我并不难过。