让我们有一个2D双数组,例如:
% Data: ID, Index, Weight, Category
A0=[1 1121 204 1;...
2 2212 112 1;...
3 2212 483 3;...
4 4334 233 1;...
5 4334 359 2;...
6 4334 122 3 ];
对于每个给定的索引,我需要通过具有最高权重的行进行数据透视/分组,这可以通过任何Pivot Table来实现。按功能分组(例如pivottable
,SQL GROUP BY或MS Excel数据透视表)
% Current Result
A1=pivottable(A0,[2],[],[3],{@max}); % Pivot Table
A1=cell2mat(A1); % Convert to array
>>A1=[1121 204;...
2212 483;...
4334 359 ]
如果我还需要恢复ID和类别列,我该如何处理?
% Required Result
>>A1=[1 1121 204 1;...
3 2212 483 3;...
5 4334 359 2 ];
语法是Matlab,但是可以接受涉及其他语言(Java,SQL)的解决方案,因为它们可以转录为Matlab。
您可以将splitapply
与匿名函数一起使用,如下所示。
grouping_col = 2; % Grouping column
maximize_col = 3; % Column to maximize
[~, ~, group_label] = unique(A0(:,grouping_col));
result = splitapply(@(x) {x(x(:,maximize_col)==max(x(:,maximize_col)),:)}, A0, group_label);
result = cell2mat(result); % convert to matrix
工作原理:@(x) {x(x(:,maximize_col)==max(···),:)}
为每个组调用一次匿名函数splitapply
。该函数作为输入提供,该子矩阵包含具有索引grouping_col
的列的相同值的所有行。此函数的作用是保留所有行,使索引为maximize_col
的列最大化,并将其打包到单元格中。然后由cell2mat
将结果转换为矩阵形式。
通过上述解决方案,如果每个组有几个最大化行,则产生所有行。要仅保留第一行,请将最后一行替换为
result = cell2mat(cellfun(@(c) c(1,:), result, 'uniformoutput', false));
它是如何工作的:这使用cellfun
将匿名函数@(c) c(1,:)
应用于每个单元格的内容。该函数只保留第一行。或者,保持最后一行使用@(c) c(end,:)
。然后使用cell2mat
将结果转换为矩阵形式。