假设我们有一个由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,:)')]
这样的东西。非常感谢任何帮助。
答案 0 :(得分:4)
假设每个单元格有两行且可变数量的列,其中第一行是ID,第二行是属性,我将所有单元格合并为一个2D矩阵并使用{{ 3}}。 accumarray
非常适合此处,因为您希望将属于同一ID的值组合在一起并对其应用函数。在我们的例子中,我们的函数只是将值放在单元格数组中,我们确保对值进行排序,因为每个ID按accumarray
分组的值以随机顺序进入函数。
使用accumarray
将单元格转换为2D矩阵,对其进行转置以使其与accumarray
兼容,然后使用它。我需要注意的一件事是,如果缺少任何ID,accumarray
将使此插槽为空。缺少的意思是,在你的例子中,缺少ID 4,因为3和5之间存在差距,并且ID 6介于5和7之间(我在评论中添加了示例)。因为数据中最大的ID是7,accumarray
的工作原理是将ID 1到ID 7的输出以1为增量进行分配。我们需要解决的最后一件事是从{的输出中消除任何空单元格。 {1}}完成分组。
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,:) = [];
如果您想在2D单元阵列上完成此操作,其中此单元阵列的每一行代表同一问题的单独实例,我的一个建议是可能遍历每一行。在评论中给出了你的例子:
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