user1618022
user1618022

Reputation: 163

concatenate vectors of an cell array in matlab

In matlab I have a 4x5 cell array where each cell consists of an 121x1 vector.

What is the easiest way to create an 3-dim 4x5x121 matrix avoiding a 2-fold loop.

Upvotes: 7

Views: 3003

Answers (4)

tmpearce
tmpearce

Reputation: 12693

How about this, avoiding cellfun:

 output=permute(cell2mat(permute(input,[3 1 2])),[2 3 1]);

Haven't compared speed to the other suggestions though.

Upvotes: 0

Jonas
Jonas

Reputation: 74930

One way (not necessarily the fastest)

%# convert all arrays in the cell array inCell to 1x1x121
permCell = cellfun(@(x)permute(x,[3,2,1]),inCell,'uniformOutput',false);

%# catenate
array = cell2mat(permCell);

Upvotes: 7

angainor
angainor

Reputation: 11810

The answers by Jonas and Rody are of course fine. A small performance refinement is to reshape your vectors in the cells rather than permute them:

permCell = cellfun(@(x)reshape(x,[1 1 numel(x)]), inCell, 'uni',false);
A = reshape([permCell{:}], [size(inCell) numel(inCell{1,1})]);

And by far the fastest, if you can relax the requirements about the output dimensions, is simply concatenating the cell vectors and reshaping

A = reshape([inCell{:}], [numel(inCell{1,1}) size(inCell)]);

which yields a [121 x 4 x 5] matrix.

Upvotes: 1

Rody Oldenhuis
Rody Oldenhuis

Reputation: 38032

Suppose

A = cellfun(@(~)rand(121,1), cell(4,5), 'uniformoutput', false)

then normally I would say

cat(3, A{:})

but that would give a 121-by-1-by-20 array. For your case, an extra step is needed:

A = cellfun(@(x)permute(x,3,2,1), A, 'uniformoutput', false)
A = reshape([A{:}], size(A,1), size(A,2), size(A{1},3))

or, alternatively,

A = cellfun(@(x)permute(x,3,2,1), A, 'uniformoutput', false)
A = cell2mat(A);

although

>> start = tic;
>> for ii = 1:1e3
>>     B1 = reshape([A{:}], size(A,1), size(A,2), size(A{1},3)); end
>> time1 = toc(start);
>> 
>> start = tic;
>> for ii = 1:1e3
>>     B2 = cell2mat(A); end
>> time2 = toc(start);
>> 
>> time2/time1
ans = 
     4.964318459657702e+00

so the command cell2mat is almost 5 times slower than the reshape of the expansion. Use whichever seems best suited for your case.

Upvotes: 4

Related Questions