Eln*_*naz 4 arrays matlab grouping vectorization
我有两个长度为16的向量.第一个,r例如:
r = [1;3;5;7;1;3;6;7;9;11;13;16;9;11;13;16];
Run Code Online (Sandbox Code Playgroud)
r包含ID列表.我想收集重复ID的索引,r以便每个组都是一个ID的索引列表.然后,我将使用这些索引访问第二个向量,a并找到每个组的索引上的最大值.
因此,我想产生使用输出向量r和a,使得:
max(a(1),a(5)), max(a(2),a(6)), a(3), a(7), max(a(4),a(8)), max(a(9),a(13)), max(a(10),a(14)), max(a(11),a(15)), max(a(12),a(16))
Run Code Online (Sandbox Code Playgroud)
我还想保留最大值的索引.如何在MATLAB中有效地实现它?
您可以使用第三个输出unique分配r唯一ID中的每个唯一编号.然后,您可以将所有共享相同ID的数字与一个accumarray调用相关联,其中键是唯一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);
Run Code Online (Sandbox Code Playgroud)
该'stable'旗unique因为我们希望出现的顺序分配唯一的ID是很重要的.不这样做会在分配ID之前先对值进行排序r,这不是我们想要的.
这是一个简单的例子.让我设置你的问题,生成一个随机的16元素数组存储a,你在其中尝试最终索引.我们还将建立r:
rng(123);
a = rand(16,1);
r = [1;3;5;7;1;3;6;7;9;11;13;16;9;11;13;16];
Run Code Online (Sandbox Code Playgroud)
这是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
Run Code Online (Sandbox Code Playgroud)
完成代码后,我们得到这个:
out =
0.7195
0.4231
0.2269
0.6848
0.9808
0.4809
0.3921
0.3980
0.7380
Run Code Online (Sandbox Code Playgroud)
您可以自己验证这会给出正确的结果.具体而言,第一元素是最大的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);
Run Code Online (Sandbox Code Playgroud)
这需要一个数组和一系列索引来访问数组,称为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));
Run Code Online (Sandbox Code Playgroud)
这就是我现在得到的:
>> out
out =
5
6
3
8
7
9
10
15
16
Run Code Online (Sandbox Code Playgroud)
如果查看每个值,这将反映a我们选择的哪个位置对应于每个组的最大值.
| 归档时间: |
|
| 查看次数: |
441 次 |
| 最近记录: |