合并不同单元格的元素

Merging elements of different cells

假设,我们有一个由 id 和一个属性组成的元胞数组,例如

A{1,1}=[1 2;2 4]
A{1,2}=[2 3 5;8 5 6] 

现在,我想要一个最终输出,其中包含两个单元格(第一行值)的唯一 ID,并且相应的列分别具有每个单元格的属性值。 即

C = 
[1]    [         2]
[2]    [1x2 double]  % 4 in first cell and 8 in second cell
[3]    [         5]
[5]    [         6]

似乎无法使用 C=[unique(A{1,:}(1,:)')] 之类的东西。非常感谢任何帮助。

假设每个单元格都有两行和数量可变的列,其中第一行是 ID,第二行是一个属性,我会将所有单元格合并到一个二维矩阵中并使用 accumarrayaccumarray 在这里非常合适,因为您想将属于同一 ID 的值分组在一起并对其应用函数。在我们的例子中,我们的函数将简单地将值放在元胞数组中,我们将确保对值进行排序,因为按每个 ID accumarray 分组的值以随机顺序进入函数。

使用 cell2mat 将单元格转换为二维矩阵,转置它以使其与 accumarray 兼容,然后使用它。我需要注意的一件事是,如果缺少任何 ID,accumarray 将使该插槽为空。我所说的缺失的意思是,在您的示例中,ID 4 缺失,因为 3 和 5 之间存在间隙,ID 6 也存在于 5 和 7 之间(我在您给我的评论中添加了示例)。因为数据中最大的 ID 是 7,所以 accumarray 通过以 1 为增量分配从 ID 1 到 ID 7 的输出。我们需要解决的最后一件事是从 accumarray完成分组。

顺便说一句,我将假设您的单元格数组由 单行 单元格组成,就像您的示例一样……所以:

%// Setup
A{1,1}=[1 2;2 4];
A{1,2}=[2 3 5;8 5 6];
A{1,3}=[7;8];

%// Convert row of cell arrays to a single 2D matrix, then transpose for accumarray
B = cell2mat(A).';

%// Group IDs together and ensure they're sorted
out = accumarray(B(:,1), B(:,2), [], @(x) {sort(x)});

%// Add a column of IDs and concatenate with the previous output
IDs = num2cell((1:numel(out)).');
out = [IDs out];

%// Any cells from the grouping that are empty, eliminate
ind = cellfun(@isempty, out(:,2));
out(ind,:) = [];

我们得到:

out = 

    [1]    [         2]
    [2]    [2x1 double]
    [3]    [         5]
    [5]    [         6]
    [7]    [         8]

>> celldisp(out(2,:))

ans{1} =

     2         

ans{2} =

     4
     8

如果您希望在二维元胞数组上完成此操作,其中此元胞数组的每一行代表同一问题的一个单独实例,我的一个建议是可能循环遍历每一行。像这样,在评论中给出你的例子:

%// Setup
A{1,1}=[1 2;2 4];
A{1,2}=[2 3 5;8 5 6];
A{1,3}=[7;8];
A{2,1}=[1 2;2 4]; 
A{2,2}=[1;7];

%// Make a cell array that will contain the output per row
out = cell(size(A,1),1);

for idx = 1 : size(A,1)
     %// Convert row of cell arrays to a single 2D matrix, then transpose for accumarray
      B = cell2mat(A(idx,:)).';

      %// Group IDs together and ensure they're sorted
      out{idx} = accumarray(B(:,1), B(:,2), [], @(x) {sort(x)});

      %// Add a column of IDs and concatenate with the previous output
      IDs = num2cell((1:numel(out{idx})).');
      out{idx} = [IDs out{idx}];

      %// Any cells from the grouping that are empty, eliminate
      ind = cellfun(@isempty, out{idx}(:,2));
      out{idx}(ind,:) = [];
end

我们得到:

>> out{1}

ans = 

    [1]    [         2]
    [2]    [2x1 double]
    [3]    [         5]
    [5]    [         6]
    [7]    [         8]

>> out{2}

ans = 

    [1]    [2x1 double]
    [2]    [         4]

>> celldisp(out{1}(2,:))

ans{1} =

     2

ans{2} =

     4
     8

>> celldisp(out{2}(1,:))

ans{1} =

     1

ans{2} =

     2
     7