Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collapsing matrix into columns

I have a 2D matrix where the № of columns is always a multiple of 3 (e.g. 250×27) - due to a repeating organisation of the results (A,B,C, A,B,C, A,B,C, and so forth). I wish to reshape this matrix to create a new matrix with 3 columns - each containing the aggregated data for each type (A,B,C) (e.g. 2250×3).

So in a matrix of 250×27, all the data in columns 1,4,7,10,13,16,19,22,25 would be merged to form the first column of the resulting reshaped matrix.

The second column in the resulting reshaped matrix would contain all the data from columns 2,5,8,11,14,17,20,23,26 - and so forth.

Is there a simple way to do this in MATLAB? I only know how to use reshape if the columns I wanted to merge were adjacent (1,2,3,4,5,6) rather than non-adjacent (1,4,7,10,13,16) etc.

like image 974
AnnaSchumann Avatar asked Nov 09 '16 11:11

AnnaSchumann


4 Answers

Shameless steal from @Divakar:

B = reshape( permute( reshape(A,size(A,1),3,[]), [1,3,2]), [], 3 );
like image 71
Rody Oldenhuis Avatar answered Nov 18 '22 13:11

Rody Oldenhuis


Let A be your matrix. You can save every third column in one matrix like: (Note that you don't have to save them as matrices separately but it makes this example easier to read).

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

Then you use reshape:

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

And finally put it all together:

A = [B C D];
like image 38
StefanM Avatar answered Nov 18 '22 13:11

StefanM


You can just treat every set of columns as a single item and do three reshapes together. This should do the trick:

[save as "reshape3.m" file in your Matlab folder to call it as a function]

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
like image 2
Patrick Avatar answered Nov 18 '22 14:11

Patrick


Lets suppose you have a 3x6 matrix 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

you extract the size of the matrix

b =size(A)

and then extract each third column for a single row

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)])

and put them in one matrix

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
like image 1
Novice_Developer Avatar answered Nov 18 '22 14:11

Novice_Developer