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

后端 未结 5 637
旧巷少年郎
旧巷少年郎 2021-01-13 21:40

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

相关标签:
5条回答
  • 2021-01-13 22:08

    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.

    0 讨论(0)
  • 2021-01-13 22:17

    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.

    0 讨论(0)
  • 2021-01-13 22:22

    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
      
    0 讨论(0)
  • 2021-01-13 22:24

    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.

    0 讨论(0)
  • 2021-01-13 22:28

    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
    
    0 讨论(0)
提交回复
热议问题