Convert cell array of cell arrays to matrix of matrices

后端 未结 5 1272
一向
一向 2021-01-05 05:37

I can convert a cell array of matrices to matrix:

>> C={[1,1]; [2,2]; [3,3]};
>> cell2mat(C)
ans =
     1     1
     2     2
     3     3
         


        
相关标签:
5条回答
  • 2021-01-05 05:50

    This should do the trick:

    cellOfCells = {{1,1}; {2,2}; {3,3}};
    cell2mat(cellfun(@cell2mat, cellOfCells, 'UniformOutput', false))
    

    Edit:

    I agree that keeping it simple is an important, but so is having fun :) So - here's a one-liner that should do the trick (and can be easily generalized for any size):

    a = {{1,1;1,1}; {2,2;2,2}; {3,3;3,3}}
    reshape(cell2mat(cellfun(@cell2mat,a, 'UniformOutput', false))', 2, 2, 3)
    
    0 讨论(0)
  • 2021-01-05 05:52

    To be honest, I never liked cell2mat for being slow, so I've come up an alternative solution using comma-separated lists instead!

    Transform a cell array of vectors

    This is fairly simple, just use the colon operator and concatenate all vectors vertically:

    C = {[1,1]; [2,2]; [3,3]};
    A = vertcat(C{:})
    

    and so we get:

    A =
        1   1
        2   2
        3   3
    

    Transform a cell array of cell arrays

    This is a bit trickier. Since it's a cell array of cell arrays, we'll have to obtain a vector of all elements by a double use of the colon and horzcat, and then reshape it into the desired matrix.

    C = {{1,1}; {2,2}; {3,3}};
    V = [size(C{1}), 1]; V(find(V == 1, 1)) = numel(C);
    A = reshape([horzcat(C{:}){:}], V)
    

    and so we get:

    A =
        1   1
        2   2
        3   3
    

    The manipulation of V makes sure that A is reshaped correctly without having to specify the output dimensions explicitly (unfortunately, I didn't find a one liner for this). This also works for multi-dimensional cell arrays as well:

    C = {{1, 1; 1, 1}; {2, 2; 2, 2}; {3, 3; 3, 3}};
    V = [size(C{1}), 1]; V(find(V == 1, 1)) = numel(C);
    A = reshape([horzcat(C{:}){:}], V)
    
    A(:,:,1) = 
        1   1
        1   1
    
    A(:,:,2) =   
        2   2
        2   2
    
    A(:,:,3) =    
        3   3
        3   3
    

    P.S

    I think the correct result for the last example should be a 6-by-2 matrix instead of a 2-by-2-by-3. However, that is not what you requested, so it's off-topic.

    0 讨论(0)
  • 2021-01-05 06:01

    I had the same error, I just commented out the lines in cell2mat that return the error and everything work fine to me.

    lines to comment out in cell2mat (51:53): (you can find them using dbstop if error)

    if cisobj || ciscell error(message('MATLAB:cell2mat:UnsupportedCellContent')); end

    I don´t think it is a good idea to change matlab functions, and I am pretty shameful of my solution myself, but it works.

    0 讨论(0)
  • 2021-01-05 06:03

    Okay, the question is a long time ago - but maybe my answer might help other readers or searchers.
    I think the best solution is nearly the idea presented by Eitan T but it is possible to do that without reshaping. For me

    C={{1,1;1,1};{2,2;2,2};{3,3;3,3}};
    A=cell2mat(cat(3,C{:}))
    

    does what was asked for - thus answers with

    A(:,:,1) =
         1     1
         1     1
    A(:,:,2) =
         2     2
         2     2
    A(:,:,3) =
         3     3
         3     3
    

    Hoping that helps.

    0 讨论(0)
  • 2021-01-05 06:12

    keep it simple

    c = {{1,1;1,1}; {2,2;2,2}; {3,3;3,3}};
    z = zeros([size(c{1}) size(c,1)]);
    
    for i=1:size(c,1)
        z(:,:,i)=cell2mat(c{i});
    end
    

    gives

    EDU>> z    
    z(:,:,1) =
    
         1     1
         1     1
    
    z(:,:,2) =
    
         2     2
         2     2    
    
    z(:,:,3) =
    
         3     3
         3     3
    
    0 讨论(0)
提交回复
热议问题