【问题标题】:Convert cell array of cell arrays to matrix of matrices将元胞数组的元胞数组转换为矩阵矩阵
【发布时间】:2012-11-24 10:40:49
【问题描述】:

我可以将矩阵元胞数组转换为矩阵:

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

没关系。但是,我想将包含其他单元格数组的单元格数组转换为矩阵:

>> C={{1,1}; {2,2}; {3,3}};    
>> cell2mat(C)
Error using cell2mat (line 53)
Cannot support cell arrays containing cell arrays or objects.

所以,期望的输出是:

>> mycell2mat({{1,1}; {2,2}; {3,3}})
ans =
     1     1
     2     2
     3     3

如何做到这一点?

编辑:

我也想为多维做同样的事情:

>> mycell2mat({{1,1;1,1}; {2,2;2,2}; {3,3;3,3}})
ans(:,:,1) =

     1     1
     1     1

ans(:,:,2) =

     2     2
     2     2

ans(:,:,3) =

     3     3
     3     3

【问题讨论】:

    标签: matlab


    【解决方案1】:

    说实话,我从不喜欢 cell2mat 的速度慢,所以我想出了一个替代解决方案,改用 comma-separated lists

    转换向量元胞数组

    这相当简单,只需使用colon 运算符和concatenate all vectors vertically

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

    所以我们得到:

    A =
        1   1
        2   2
        3   3
    

    转换元胞数组的元胞数组

    这有点棘手。由于它是元胞数组的元胞数组,我们必须通过双重使用冒号和horzcat 来获得所有元素的向量,然后将reshape 放入所需的矩阵中。

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

    所以我们得到:

    A =
        1   1
        2   2
        3   3
    

    V 的操作确保 A 被正确地重塑,而无需明确指定输出尺寸(不幸的是,我没有找到一个唯一的衬里)。这也适用于多维元胞数组:

    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
    

    附言

    我认为最后一个示例的正确结果应该是 6×2 矩阵,而不是 2×2×3。然而,这不是你要求的,所以它是题外话。

    【讨论】:

      【解决方案2】:

      这应该可以解决问题:

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

      编辑:

      我同意保持简单很重要,但玩得开心也很重要 :) 所以 - 这是一个可以解决问题的单行代码(并且可以很容易地推广到任何大小):

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

      【讨论】:

      • 谢谢 Ronnyle,这适用于我举的一维单元格。但我也需要对多维做同样的事情。你能用这种方式改进你的答案吗?
      【解决方案3】:

      保持简单

      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
      

      给予

      EDU>> z    
      z(:,:,1) =
      
           1     1
           1     1
      
      z(:,:,2) =
      
           2     2
           2     2    
      
      z(:,:,3) =
      
           3     3
           3     3
      

      【讨论】:

        【解决方案4】:

        好的,这个问题是很久以前的问题了 - 但也许我的回答可能会帮助其他读者或搜索者。
        我认为 最好的 解决方案几乎是 Eitan T 提出的想法,但可以在不重塑的情况下做到这一点。对我来说

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

        按照要求做 - 因此回答

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

        希望对您有所帮助。

        【讨论】:

          【解决方案5】:

          我遇到了同样的错误,我只是注释掉了 cell2mat 中返回错误的行,并且一切正常。

          在 cell2mat (51:53) 中注释掉的行:(如果出现错误,您可以使用 dbstop 找到它们)

          如果 cisobj ||顺式细胞 错误(消息('MATLAB:cell2mat:UnsupportedCellContent')); 结束

          我认为更改 matlab 函数不是一个好主意,我自己也为自己的解决方案感到羞耻,但它确实有效。

          【讨论】: