【问题标题】:Nested indexing in a loop循环中的嵌套索引
【发布时间】:2026-02-15 13:45:01
【问题描述】:

我有一个for 循环执行当前操作:

T = [1,1,1,4,5,6,3];
A = [20,15,4,21,14,3];
l = length(T);

% how can we vectorize this?
for(i = 1:l)
    A(T(i)) = A(T(i)) + 1;
end

简单地说,它使用T 向量作为索引列表,以特定顺序在A 数组上递增。例如,数组A 中的第一个元素将增加 3 次(对应于T 中的 3 个元素),而其余的将增加一次,2 不会增加。因此,A 的更改结果如下:

A = [23,15,5,22,15,4];

但是,理想情况下,我想在这里避免 for 循环。在我尝试之前:

A(T) = A(T) + 1;

这不起作用; MATLAB 只是忽略重复的索引。有没有办法通过矢量化或其他方式在for 循环中执行操作?

【问题讨论】:

    标签: matlab for-loop indexing vectorization


    【解决方案1】:

    accumarray:

    T = [1,1,1,4,5,6,3];
    A = [20,15,4,21,14,3];
    res = A + accumarray(T(:), 1, [numel(A) 1]).';
    

    【讨论】:

    • A + accumarray(T(:), 1, [numel(A) 1])'否则Matlab报错:当SUBS是列向量时,第三个输入SZ必须是[N 1]的形式。
    • 还有s = accumarray(T(:),1).'; w = 1:numel(s); A(w) = A(w)+s;
    【解决方案2】:
    [q,w] = hist(T,0:numel(A));
    A(w(q>0)) = A(w(q>0)) + q(q>0);
    
    
    A =
    
    23    15     5    22    15     4
    

    解释:

    您可以使用hist 了解每个索引在T 中出现的次数。 由于索引是整数,因此您可以指定从 0 到 A 的元素数的范围。

    Hist 然后会返回两个向量:

    q 是每个索引的出现次数:

    q =
    
    0     3     0     1     1     1     1     0     0     0     0
    

    w 是索引本身:

    w =
    
    0     1     2     3     4     5     6     7     8     9    10
    

    然后您只需将至少出现一次的索引w(q>0) 作为要更新的 A 的索引,然后将这些索引更新为出现次数q(q>0)

    【讨论】: