Reputation: 1271
I have a cell-array of matrices (A
):
And want to convert this into a singular 2D matrix by padding each column to an equal length (in this case - 197) and reshaping it in a specific manner such A{1,1} occupies the first three columns of the output matrix, A{1,2} occupies the next three and so forth.
The latter can likely be achieved via horzcat
however I am not sure how to pad a cell array when each cell contains a matrix - rather than a vector, where i'd normally use something along the lines of:
Lmax = max(max(cell2mat(cellfun(@numel,A,'un',0)))) ;
b = cellfun(@(c)[c(:);NaN(Lmax-numel(c),1)],A,'uniformoutput',0);
Padding with either NaNs or 0's is acceptable.
How can I do this?
Upvotes: 1
Views: 177
Reputation: 221684
Almost vectorized approach with bsxfun
's masking capability -
%// Set parameters
nrows = cellfun('size',A,1)
ncols = size(A{1,1},2)
maxr = max(nrows)
%// Get mask
mask = bsxfun(@le,[1:maxr]',nrows) %//'
out = zeros(maxr*numel(nrows),ncols)
out(mask(:),:) = vertcat(A{:})
%// Final output
b = reshape(permute(reshape(out,maxr,numel(nrows),[]),[1 3 2]),maxr,[])
Sample run -
>> A{1,1}
ans =
5 6 2
6 9 1
4 7 1
4 4 2
5 8 3
>> A{1,2}
ans =
3 5 2
1 1 6
>> A{1,3}
ans =
8 5 5
9 5 1
6 3 8
9 4 1
>> A{1,4}
ans =
4 8 4
>> b
b =
5 6 2 3 5 2 8 5 5 4 8 4
6 9 1 1 1 6 9 5 1 0 0 0
4 7 1 0 0 0 6 3 8 0 0 0
4 4 2 0 0 0 9 4 1 0 0 0
5 8 3 0 0 0 0 0 0 0 0 0
Upvotes: 1
Reputation: 16354
Instead of numel
you need to use size
, then the following modification of your code works:
Lmax = max(cellfun('size',A,1));
b = cellfun(@(c)[c;NaN(Lmax-size(c,1),3)],A,'uniformoutput',0);
c = horzcat(b{:}); % this holds your final matrix
Upvotes: 0
Reputation: 11812
This is just an extension of the previous answer to your question Pad cell array with whitespace and rearrange.
The method is exactly the same, the only trick now you have matrices instead of vectors is to use size
instead of numel
.
It becomes:
%// sample data
A = { randi(10,5,3) , randi(10,8,3) ; randi(10,6,3) , randi(10,3,3) }
A =
[5x3 double] [8x3 double]
[6x3 double] [3x3 double]
Using the same method (replacing numel
with size(...,1)
to get the number of lines right:
%%
nCol = 3 %// number of columns for the padding lines
%// get the length of the longest vector
Lmax = max(max( cellfun('size',A,1) )) ;
%// pad columns with necessary number of NaN
b = cellfun( @(c) [c ; NaN(Lmax-size(c,1),nCol)], A ,'un',0 ) ;
%// reshape if you want your cell array in columns
b = b(:).'
>> b
b =
[8x3 double] [8x3 double] [8x3 double] [8x3 double]
Upvotes: 1