Giu*_*ppe 2 matlab for-loop labels
我需要在matlab中找到具有相同标签的值中的最大值,并且我试图避免使用for循环.
具体来说,我有一个L标签数组和一个V相同大小的值数组.我需要生成一个数组S,其中包含每个值L的最大值V.一个例子将更好地解释:
L = [1,1,1,2,2,2,3,3,3,4,4,4,1,2,3,4]
V = [5,4,3,2,1,2,3,4,5,6,7,8,9,8,7,6]
Run Code Online (Sandbox Code Playgroud)
然后,输出数组S的值将是:
s(1) = 9 (the values V(i) such that L(i) == 1 are: 5,4,3,9 -> max = 9)
s(2) = 8 (the values V(i) such that L(i) == 2 are: 2,1,2,8 -> max = 8)
s(3) = 7 (the values V(i) such that L(i) == 3 are: 3,4,5,7 -> max = 7)
s(4) = 8 (the values V(i) such that L(i) == 4 are: 6,7,8,6 -> max = 8)
Run Code Online (Sandbox Code Playgroud)
这可以通过遍历数组L和Vfor循环来实现,但在Matlab中循环很慢,所以我一直在寻找更快的解决方案.任何的想法?
这是一项标准工作accumarray.
需要考虑三种情况,通用性越来越高:
你可以使用
S = accumarray(L(:), V(:), [], @max).';
Run Code Online (Sandbox Code Playgroud)
在你的例子中,这给出了
>> L = [1 1 1 2 2 2 3 3 3 4 4 4 1 2 3 7];
>> V = [5 4 3 2 1 2 3 4 5 6 7 8 9 8 7 6];
>> S = accumarray(L(:), V(:), [], @max).'
S =
9 8 7 8
Run Code Online (Sandbox Code Playgroud)
如果有整数之间的缝隙中L,上面会给出一个0为不存在的标签结果.如果要更改该填充值(例如,更改NaN),请在以下位置使用第五个输入参数acccumarray:
S = accumarray(L(:), V(:), [], @max, NaN).';
Run Code Online (Sandbox Code Playgroud)
例:
>> L = [1 1 1 2 2 2 3 3 3 4 4 4 1 2 3 7]; %// last element changed
>> V = [5 4 3 2 1 2 3 4 5 6 7 8 9 8 7 6]; %// same as in your example
>> S = accumarray(L(:), V(:), [], @max, NaN).'
S =
9 8 7 8 NaN NaN 6
Run Code Online (Sandbox Code Playgroud)
当整数标签之间的间隙很大时,使用填充值可能效率低.在这种情况下,您可能希望仅获取有意义的值S,而不使用填充值,即跳过不存在的标签.而且,可能是L 不一定包含整数的情况.
这两个问题通过unique在使用前应用于标签来解决accumarray:
[~, ~, Li] = unique(L); %// transform L into consecutive integers
S = accumarray(Li(:), V(:), [], @max, NaN).';
Run Code Online (Sandbox Code Playgroud)
例:
>> L = [1.5 1.5 1.5 2 2 2 3 3 3 4 4 4 1 2 3 7.8]; %// note: non-integer values
>> V = [5 4 3 2 1 2 3 4 5 6 7 8 9 8 7 6 ]; %// same as in your example
>> [~, ~, Li] = unique(L); %// transform L into consecutive integers
>> S = accumarray(Li(:), V(:), [], @max, NaN).'
S =
9 5 8 7 8 6
Run Code Online (Sandbox Code Playgroud)