Search code examples
matlabmatrixcell-array

Change the format of a cell array Matlab


I have a A which is 640x1 cell, where the value of each cell A(i,1) varies from row to row, for example:

A(1,1)=[]
A(2,1)=[1]
A(3,1)=[1,2,3]

What I want to do is to convert A to be like this:

A(1,1)=[]
A(2,1)=1
A(3,1)=1; A(3,2)=2; A(3,3)=3

so that each cell has only one value. So if anyone could assist me how can I do this? This is a part of who A looks like

A=
[]
0
0
0
145
[144;192]
[145;197;307]

Solution

  • Example:

    % first lets create some random cellarray containing data of different length
    A = cell(10,1);
    for i=1:numel(A)
        A{i} = rand(1,randi([0 5]));
    end
    
    % determine the maximum number of columns
    colnum = max(cellfun(@numel, A));
    
    % create new cellarray, and fill each row
    B = cell(numel(A),colnum);
    for i=1:numel(A)
        if isempty(A{i}), continue; end
        B(i,1:numel(A{i})) = num2cell(A{i});
    end
    

    So I had the first cell array as:

    >> celldisp(A)
    A{1} =
        0.2217    0.1174    0.2967    0.3188
    A{2} =
        0.5079    0.0855
    A{3} =
        0.8010
    A{4} =
         []
    A{5} =
        0.7303    0.4886    0.5785    0.2373    0.4588
    A{6} =
        0.5468    0.5211    0.2316    0.4889    0.6241
    A{7} =
        0.3955    0.3674    0.9880    0.0377
    A{8} =
        0.9133    0.7962    0.0987    0.2619    0.3354
    A{9} =
        0.1366    0.7212    0.1068    0.6538
    A{10} =
        0.7791    0.7150
    

    which turned into:

    >> B
    B = 
        [0.2217]    [0.1174]    [0.2967]    [0.3188]          []
        [0.5079]    [0.0855]          []          []          []
        [0.8010]          []          []          []          []
              []          []          []          []          []
        [0.7303]    [0.4886]    [0.5785]    [0.2373]    [0.4588]
        [0.5468]    [0.5211]    [0.2316]    [0.4889]    [0.6241]
        [0.3955]    [0.3674]    [0.9880]    [0.0377]          []
        [0.9133]    [0.7962]    [0.0987]    [0.2619]    [0.3354]
        [0.1366]    [0.7212]    [0.1068]    [0.6538]          []
        [0.7791]    [0.7150]          []          []          []
    

    where we access elements as a 2D cell array:

    >> B{5,3}
    ans =
        0.5785
    

    EDIT:

    Here is a slightly different implementation:

    len = cellfun(@numel, A);
    padding = arrayfun(@(n)cell(1,n), max(len)-len, 'UniformOutput',false);
    B = cellfun(@num2cell, A, 'UniformOutput',false);
    B = cellfun(@(b,pad) [b{:} pad], B, padding, 'UniformOutput',false);
    B = cat(1, B{:});
    

    EDIT2:

    Note that the above will return a 2D cell array. This is because regular numeric matrices cannot be jagged (all rows must have the same length).

    If you want to get a 2D numeric matrix, you'll have to insert NaN values as fillers:

    C = B;
    C(cellfun(@isempty,C))= {NaN};
    C = cell2mat(C)
    

    the output:

    >> C
    C =
        0.2217    0.1174    0.2967    0.3188       NaN
        0.5079    0.0855       NaN       NaN       NaN
        0.8010       NaN       NaN       NaN       NaN
           NaN       NaN       NaN       NaN       NaN
        0.7303    0.4886    0.5785    0.2373    0.4588
        0.5468    0.5211    0.2316    0.4889    0.6241
        0.3955    0.3674    0.9880    0.0377       NaN
        0.9133    0.7962    0.0987    0.2619    0.3354
        0.1366    0.7212    0.1068    0.6538       NaN
        0.7791    0.7150       NaN       NaN       NaN