2

假设我们有一个数组

A = zeros([1,10]);

我们有几个可能重复的索引说:

indSeq = [1,1,2,3,4,4,4];

我们如何增加索引序列中A(i)的数量,iA(1) = 2, A(2) = 1, A(3) = 1, A(4) = 3

代码A(indSeq) = A(indSeq)+1不起作用。

我知道我可以使用以下 for 循环来实现目标,但我想知道是否有无论如何我们可以避免 for 循环?我们可以假设indSeq是排序的。

一个for循环解决方案:

for i=1:length(indSeq)
  A(indSeq(i)) = A(indSeq(i))+1;
end;
4

3 回答 3

3

您可以将accumarray其用于此类基于标签的计数作业,如下所示 -

accumarray(indSeq(:),1)

基准测试

正如 中所建议的other answer,您也可以使用hist/histc. 让我们针对大数据量对这两个进行基准测试。我使用的基准代码有 -

%// Create huge random array filled with ints that are duplicated & sorted
maxn = 100000;
N = 10000000;
indSeq = sort(randi(maxn,1,N));

disp('--------------------- With HISTC')
tic,histc(indSeq,unique(indSeq));toc

disp('--------------------- With ACCUMARRAY')
tic,accumarray(indSeq(:),1);toc

运行时输出 -

--------------------- With HISTC
Elapsed time is 1.028165 seconds.
--------------------- With ACCUMARRAY
Elapsed time is 0.220202 seconds.
于 2015-12-17T06:54:58.383 回答
1

这是运行长度编码,下面的代码应该可以为您解决问题。

A=zeros(1,10);
indSeq = [1,1,2,3,4,4,4,7,1];
indSeq=sort(indSeq); %// if your input is always sorted, you don't need to do this
pos = [1; find(diff(indSeq(:)))+1; numel(indSeq)+1];
A(indSeq(pos(1:end-1)))=diff(pos)

返回

A =
     3     1     1     3     0     0     1     0     0     0

该算法由 Luis Mendo 为 MATL 编写。

于 2015-12-17T03:29:57.690 回答
1

我认为您正在寻找的是数组唯一值的出现次数。这可以通过以下方式完成:

[num, val] = hist(indSeq,unique(indSeq));

你的例子的输出是:

num = 2 1 1 3
val = 1 2 3 4

所以 num 是 val 出现的次数。即数字 1 在您的示例中出现 2 次

于 2015-12-17T04:45:01.433 回答