如何通过 MATLAB 中的特定值递增数组中的某些元素
How to increment some of elements in an array by specific values in MATLAB
假设我们有一个数组
A = zeros([1,10]);
我们有几个可能重复的索引说:
indSeq = [1,1,2,3,4,4,4];
我们怎样才能将 A(i)
增加索引序列中 i
的数量,即 A(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;
这是 运行 长度编码,下面的代码应该可以解决问题。
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)
哪个returns
A =
3 1 1 3 0 0 1 0 0 0
此算法由 Luis Mendo 为 MATL 编写。
我想你要找的是数组中唯一值的出现次数。这可以通过以下方式完成:
[num, val] = hist(indSeq,unique(indSeq));
您的示例的输出是:
num = 2 1 1 3
val = 1 2 3 4
所以num是val出现的次数。即数字 1 在您的示例中出现了 2 次
您可以使用 accumarray
进行此类基于标签的计数工作,例如 -
accumarray(indSeq(:),1)
基准测试
如 中的建议,您也可以使用 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.
假设我们有一个数组
A = zeros([1,10]);
我们有几个可能重复的索引说:
indSeq = [1,1,2,3,4,4,4];
我们怎样才能将 A(i)
增加索引序列中 i
的数量,即 A(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;
这是 运行 长度编码,下面的代码应该可以解决问题。
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)
哪个returns
A =
3 1 1 3 0 0 1 0 0 0
此算法由 Luis Mendo 为 MATL 编写。
我想你要找的是数组中唯一值的出现次数。这可以通过以下方式完成:
[num, val] = hist(indSeq,unique(indSeq));
您的示例的输出是:
num = 2 1 1 3
val = 1 2 3 4
所以num是val出现的次数。即数字 1 在您的示例中出现了 2 次
您可以使用 accumarray
进行此类基于标签的计数工作,例如 -
accumarray(indSeq(:),1)
基准测试
如 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.