سؤال

I have a simple question but I can't figure it out or find it anywhere. I have a cell array where c{1} is a vector and c{2} is a vector but of different lengths, up to c{i}. What I want is one vector that is [c{1};c{2};c{3}...c{i}]. What is the most efficient way to do this?

هل كانت مفيدة؟

المحلول

The following one-liner even works for completely inconsistent inputs:

result = [cell2mat(cellfun(@(x) x(:), A, 'uni', 0)')]'

Example:

for:

A{1} = [1, 2, 3, 4, 5];
A{2} = [6; 7; 8; 9];
A{3} = [10, 12; 11, 13];

it returns:

result =

     1     2     3     4     5     6     7     8     9    10    11    12    13

نصائح أخرى

Matlab/Octave allows this king of really-not-efficient but very-convenient notation, assuming a is a structure only containing column-vectors:

x = [];             #% A fresh new vector/matrix/tensor, who knows?
for i=1:numel(a)    #% parse container item by item
   x = [x;a{i}];    #% append container item a{i} to x in a column-fashion way
end

This will works but it is bloody inefficient since it will reallocate x each for step and it is not bulletproof (no error handling, no type checking): therefore it will fail if it encounters anything (matrix, string, row vector) but column vector which are likely to be found in such containers.

Anyway, it will ease a not-so-stringent-and-heuristic design, but please consider reimplementing when robust design is needed.

You can padding each cell with zeros, and align the lengths to the longest cell vector. It is done in a loop by iterating each cell vector.

This depends on whether the vectors in c are row or column vectors. But usually the fastest and most compact ways are:

c={[1 2 3], [4 5 6 7 8], [9 10]}
cell2mat(c)
cat(2, c{:})

or

c={[1 2 3]', [4 5 6 7 8]', [9 10]'}
% cell2mat(c) % Doesn't work.
cat(1, c{:})

so personally, I prefer cat.

In Matlab; without loops:

  1. If the cell array contains column vectors and you want to arrange them into one big column vector:

    result = vertcat(c{:}); %// vertically concat all vectors
    

    Example:

    >> c = {[1;2], [1;2;3]};
    >> result = vertcat(c{:})
    result =
         1
         2
         1
         2
         3
    
  2. If the cell array contains row vectors, you can arrange them as rows of a matrix, filling non-existent values with NaN (or any other value):

    M = max(cellfun(@numel, c)); %// max length of vectors
    c2 = cellfun(@(row)[row NaN(1,M-numel(row))], c, 'uni', 0); %// fill with NaN
    result = vertcat(c2{:}); %// concat all equal-size row vectors into a matrix
    

    Example:

    >> c = {[1 2], [1 2 3]};
    >> M = max(cellfun(@numel, c));
    >> c2 = cellfun(@(row)[row NaN(1,M-numel(row))], c, 'uni', 0);
    >> result = vertcat(c2{:})
    result =
         1     2   NaN
         1     2     3
    
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top