Convert cell array of cell arrays to matrix of matrices

匿名 (未验证) 提交于 2019-12-03 02:20:02

问题:

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 

This is OK. But, I want to convert a cell array including other cell arrays to a matrix:

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

So, desired output is:

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

How to do this?

Edit:

I want to do same thing for multidimensional ones also:

>> 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 

回答1:

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.



回答2:

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) 


回答3:

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 


回答4:

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.



回答5:

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



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