MATLAB/OCTAVE Extracting elements from different sized vectors in a cell array

て烟熏妆下的殇ゞ 提交于 2019-12-01 04:59:25

问题


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?


回答1:


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



回答2:


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.




回答3:


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.




回答4:


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.




回答5:


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
    


来源:https://stackoverflow.com/questions/20891219/matlab-octave-extracting-elements-from-different-sized-vectors-in-a-cell-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!