您可以使用unique 的第三个输出为r 中的每个唯一编号分配唯一ID。然后,您可以使用 accumarray 调用将所有共享相同 ID 的数字分箱,其中键是唯一 ID,值是 a 在此唯一 ID 数组中键的对应位置的实际值。收集所有这些值后,请使用 accumarray,以便您可以将这些值用于 r 中的每个唯一值,以引用 a 并选择最大元素:
%// Define r and a
r = [1;3;5;7;1;3;6;7;9;11;13;16;9;11;13;16];
a = [...];
%// Relevant code
[~,~,id] = unique(r, 'stable');
out = accumarray(id(:), a(:), [], @max);
unique 中的 'stable' 标志很重要,因为我们希望按出现的顺序分配唯一的 ID。不这样做会在分配 ID 之前先对r 中的值进行排序,这不是我们想要的。
这是一个简单的例子。让我来设置您的问题,即生成一个存储在您试图最终索引的a 中的随机 16 元素数组。我们还将设置r:
rng(123);
a = rand(16,1);
r = [1;3;5;7;1;3;6;7;9;11;13;16;9;11;13;16];
这是a 的样子:
>> a
a =
0.6965
0.2861
0.2269
0.5513
0.7195
0.4231
0.9808
0.6848
0.4809
0.3921
0.3432
0.7290
0.4386
0.0597
0.3980
0.7380
运行代码后,我们得到:
out =
0.7195
0.4231
0.2269
0.6848
0.9808
0.4809
0.3921
0.3980
0.7380
您可以自己验证这是否给出了正确的结果。具体来说,第一个元素是a(1)和a(5)的最大值,分别为0.6965和0.7195,最大值为0.7195。同理,第二个元素是最大值a(2)和a(6),分别是0.2861和0.4231,最大值是0.4231等等。
如果您还希望记住用于选择最大元素的索引是什么,这会稍微复杂一些。您需要做的是再次调用accumarray,但值不会是a 的值,而是实际的索引值。您将使用max 的第二个输出来获取所选值的实际位置。然而,由于max 的性质,我们不能只获取max 的第二个元素而不显式调用max 的双输出版本(我真的希望有另一种解决方法...... Python 有NumPy 中的一个名为numpy.argmax 的函数,它不能正确封装在匿名函数中(即@(x) ...),因此您需要创建一个自定义函数来执行此操作。
创建一个名为maxmod 的新函数并将其保存到一个名为maxmod.m 的文件中。你可以把它放在函数中:
function p = maxmod(vals, ind)
[~,ii] = max(vals(ind));
p = ind(ii);
这需要一个数组和一系列索引来访问该数组,称为vals。然后我们会找到这些选定结果中的最大值,然后返回哪个索引给了我们最大值。
之后,您可以像这样调用accumarray:
%// Define r and a
r = [1;3;5;7;1;3;6;7;9;11;13;16;9;11;13;16];
a = [...];
%// Relevant code
[~,~,id] = unique(r, 'stable');
out = accumarray(id(:), (1:numel(r)).', [], @(x) maxmod(a,x));
这就是我现在得到的:
>> out
out =
5
6
3
8
7
9
10
15
16
如果您查看每个值,这会反映我们选择的 a 的哪个位置对应于每个组的最大值。