查找单元阵列中唯一的行集最大值

时间:2015-08-10 17:30:50

标签: arrays matlab

我有一个看起来像的单元格数组:

 ID         Weight    Position
'img1'    [23.6793]    [6]
'img1'    [22.6368]    [2]
'img1'    [22.8294]    [4]
'img2'    [24.3452]    [8]
'img2'    [25.0608]    [3]
'img2'    [25.2548]    [9]
'img2'    [27.1751]    [12]
'img2'    [25.7463]    [5]
'img2'    [23.6599]    [2]
'img3'    [27.1899]    [4]
'img3'    [28.0790]    [1]
'img3'    [27.6633]    [2]
'img3'    [28.9362]    [3]

我想创建一个新列,其中包含每个ID的最大权重以及该最大权重的位置。结果应如下所示:

 ID         Weight    Position   Max_Weight    Max_Weight_Pos
'img1'    [23.6793]    [6]        [23.6793]      [6]
'img1'    [22.6368]    [2]        [23.6793]      [6]
'img1'    [22.8294]    [4]        [23.6793]      [6]
'img2'    [24.3452]    [8]        [27.1751]      [12]
'img2'    [25.0608]    [3]        [27.1751]      [12]
'img2'    [25.2548]    [9]        [27.1751]      [12]
'img2'    [27.1751]    [12]       [27.1751]      [12]
'img2'    [25.7463]    [5]        [27.1751]      [12]
'img2'    [23.6599]    [2]        [27.1751]      [12]
'img3'    [27.1899]    [4]        [28.9362]      [3]
'img3'    [28.0790]    [1]        [28.9362]      [3]
'img3'    [27.6633]    [2]        [28.9362]      [3]
'img3'    [28.9362]    [3]        [28.9362]      [3]

有一种简单的方法吗?

感谢。

2 个答案:

答案 0 :(得分:3)

这是accumarray的工作:

[~,~,u] = unique(data(:,1));
maxima = accumarray(u,[data{:,2}],[],@max)
temp = cell2mat(data(:,[2,3]))
pos = accumarray(u,1:size(data,1),[],@(x) getfield(sortrows( temp(x,:),1),{numel(x),2}) )
output = [data num2cell(maxima(u)) num2cell(pos(u))]

我使用了@max,因为您要求最大值,您的输出实际显示为@min。但是你可以应用任何函数(@mean等)。

答案 1 :(得分:0)

首先让我们重新创建你的单元格数组:

>> C = {'img1'    [23.6793]    [6]
'img1'    [22.6368]    [2]
'img1'    [22.8294]    [4]
'img2'    [24.3452]    [8]
'img2'    [25.0608]    [3]
'img2'    [25.2548]    [9]
'img2'    [27.1751]    [12]
'img2'    [25.7463]    [5]
'img2'    [23.6599]    [2]
'img3'    [27.1899]    [4]
'img3'    [28.0790]    [1]
'img3'    [27.6633]    [2]
'img3'    [28.9362]    [3]};

我将以另一种方式处理此问题,而不是按照路径使用accumarray ....但如果我有机会,我会这样做!

我的另一个建议是循环遍历所有唯一标签,找到组内的最大值并获取相应的位置信息以及每组的最大值。

这样的事情:

%// Get the labels
labels = unique(C(:,1));

%// Convert data and positions to numerical
data = vertcat(C{:,2});
positions = vertcat(C{:,3});

%// To store the maximum values and positions of each group
out_data = zeros(size(labels,1), 1);
pos_data = out_data;

for idx = 1 : numel(labels)
    lbl = labels{idx}; %// Get the ith label

    %// Determine the indices of the labels that match
    ind = strcmp(lbl, C(:,1));

    %// Get the numbers and positions
    num = data(ind);
    pos = positions(ind);

    %// Find maximum value and position
    [out_data(idx) ind] = max(num);
    pos_data(idx) = pos(ind);
end

% // Now place into cell array
C(:,4) = num2cell(out_data(id));
C(:,5) = num2cell(pos_data(id));

我们得到:

>> C

C = 

    'img1'    [23.6793]    [ 6]    [23.6793]    [ 6]
    'img1'    [22.6368]    [ 2]    [23.6793]    [ 6]
    'img1'    [22.8294]    [ 4]    [23.6793]    [ 6]
    'img2'    [24.3452]    [ 8]    [27.1751]    [12]
    'img2'    [25.0608]    [ 3]    [27.1751]    [12]
    'img2'    [25.2548]    [ 9]    [27.1751]    [12]
    'img2'    [27.1751]    [12]    [27.1751]    [12]
    'img2'    [25.7463]    [ 5]    [27.1751]    [12]
    'img2'    [23.6599]    [ 2]    [27.1751]    [12]
    'img3'    [27.1899]    [ 4]    [28.9362]    [ 3]
    'img3'    [28.0790]    [ 1]    [28.9362]    [ 3]
    'img3'    [27.6633]    [ 2]    [28.9362]    [ 3]
    'img3'    [28.9362]    [ 3]    [28.9362]    [ 3]