在Matlab中反转嵌套单元格数组的顺序

时间:2016-12-01 12:26:51

标签: matlab cell-array

我想知道是否可以在Matlab中反转嵌套单元格数组的顺序。

如果我有一个单元格数组 A{a,b}{c,d} 有没有办法把它转换成 B{c,d}{a,b}

目的是获得 C={c,d}(a,b) 能够在a和之后总结b。

如果我这样做 C=cellfun(@cell2mat, A, 'UniformOutput', false); 然后C将具有C{a,b}(c,d)形状,这对我没有任何帮助。

我将不胜感激任何帮助,提示或评论。

安娜

1 个答案:

答案 0 :(得分:0)

不确定A变量是否具有A{a,b}{c,d}级别的数字或更多嵌套单元格,但如果我们假设单元格中有单个数字,则可以在2个短步骤中完成此任务

  1. 压扁你的牢房
  2. 按重新安排顺序建立
  3. 让我们先创建一些测试数据。为了便于代码验证,每个值都是通过模式的原始位置/索引信息构建的:ab.cd。例如,A{1,4}{2,3}的值为14.23

    % Index size
    a = 5;
    b = 4;
    c = 3;
    d = 2;
    
    % Cell values
    [ai, bi] = ind2sub([a b], 1:a*b);
    abVal = 10*ai + bi;
    [ci,di] = ndgrid(1:c,1:d);
    cdVal = ci/10+di/100;
    
    % Built up A
    A = cell(a,b);
    for i = 1:numel(A)
        A{i} = num2cell(abVal(i) + cdVal);
    end
    

    此处真的不需要num2cell,但可以更好地模仿您的数据。如果您有数字(不是单元格)或更深的嵌套单元格,则可能必须在下面的最后一行中使用括号(:)而不是大括号{:}。但是对于这个例子,以下是这样做的。

    % Flatten the 2-level nested cell  (could use vercat instead of horcat)
    A_flat = horzcat(A{:});
    A_flat = horzcat(A_flat{:}); % Could also use [A_flat{:}] here
    

    现在使用这样的事实:值被放置在偶数索引距离并挑选出非常c x b的值。

    % Built up re-arrange cell
    A_reOrdered = cell(c,d);
    for i = 1:c*d
        A_reOrdered{i} = reshape(A_flat(i:c*d:end), a, b);
    end
    

    在这里,我实际上从A{a,b}{c,d}转变为A{c,d}(a,b)。如果您想要底部的单元结构,即A{c,d}{a,b},只需在num2cell循环中的reshape之前放置for

    对于一些示例valus:

    >> A_reOrdered{3,1}
    ans =
            11.31        12.31        13.31        14.31
            21.31        22.31        23.31        24.31
            31.31        32.31        33.31        34.31
            41.31        42.31        43.31        44.31
            51.31        52.31        53.31        54.31
    
    >> A_reOrdered{3,1}(5,2)
    ans =
            52.31
    

    最初位于

    >> A{5,2}{3,1}
    ans =
            52.31
    

    但是,如果目标确实是计算一些总和,那么您可以在展平步骤之后停止并直接对该数据进行操作。研究A_flat的模式,我想你会看到它。

    例如,对特定' b'

    的所有值求和
    nB = a*c*d;
    for ib = 1:b
        bSum(ib) = sum(A_flat((ib-1)*nB + (1:nB)));
    end
    
    % ... or without the for-loop
    bSum = arrayfun(@(x) sum(A_flat(x + (1:nB))), nB*(0:b-1));
    
    bSum =
           936.45       966.45       996.45       1026.5