4

Let's say I have A = [1:8; 11:18; 21:28; 31:38; 41:48] Now I would like to move everything from column 4 onward to the row position. How do I achieve this?

A =
     1     2     3     4     5     6     7     8
    11    12    13    14    15    16    17    18
    21    22    23    24    25    26    27    28
    31    32    33    34    35    36    37    38
    41    42    43    44    45    46    47    48

to

A2 =

     1     2     3     4    
    11    12    13    14    
    21    22    23    24    
    31    32    33    34    
    41    42    43    44    
     5     6     7     8
    15    16    17    18
    35    36    37    38
    45    46    47    48

reshape doesn't seem to do the trick

Robert Seifert
  • 25,078
  • 11
  • 68
  • 113
Gregor Isack
  • 1,111
  • 12
  • 25

3 Answers3

10

Here's a vectorized approach with reshape and permute -

reshape(permute(reshape(a,size(a,1),4,[]),[1,3,2]),[],4)

Making it generic, we could introduce the number of columns as a parameter. Hence, let ncols be that one. So, the solution becomes -

ncols = 4
reshape(permute(reshape(a,size(a,1),ncols,[]),[1,3,2]),[],ncols)

Sample run -

>> a
a =
    20    79    18    82    27    23    59    66    46    21    48    95
    96    83    46    49    34    88    23    42    17    27    15    54
    11    88    34    92    23    62    86    56    32    32    91    54
>> reshape(permute(reshape(a,size(a,1),4,[]),[1,3,2]),[],4)
ans =
    20    79    18    82
    96    83    46    49
    11    88    34    92
    27    23    59    66
    34    88    23    42
    23    62    86    56
    46    21    48    95
    17    27    15    54
    32    32    91    54

More info on the intuition behind such a General idea for nd to nd transformation, which even though originally was meant for NumPy/Python, extends to any programming paradigm in general.

horro
  • 1,262
  • 3
  • 20
  • 37
Divakar
  • 218,885
  • 19
  • 262
  • 358
3

Use Matrix indexing!

B=[A(:,1:4);A(:,5:8)]

In a loop...

for ii=0:floor(size(A,2)/4)-1
   B([1+5*ii:5*(ii+1)],:)=A(:,[1+4*ii:4*(ii+1)] );
end
Ander Biguri
  • 35,140
  • 11
  • 74
  • 120
2

One more... perhaps unoptimized way would be to decompose the matrix into cells row-wise, transpose the cell array then concatenate everything back together:

B = cell2mat(mat2cell(A, size(A, 1), 4 * ones((size(A, 2) / 4), 1)).');

The above first uses mat2cell to decompose the matrix into non-overlapping cells. Each cell has the same number of rows as A but the total number of columns is 4 and there are exactly size(A, 2) / 4 of them. As such, we need to indicate a vector of ones where each element is 4 and there are size(A, 2) / 4 of these to tell us the number of columns for each cell. This creates a row-wise cell array and so we transpose this cell array and merge all of the cells together into one final matrix with cell2mat.

rayryeng
  • 102,964
  • 22
  • 184
  • 193