计算矩阵值的频率,包括0

时间:2016-05-08 21:09:23

标签: performance matlab loops vector frequency

我有一个载体

A = [ 1 1 1 2 2 3 6 8 9 9 ]

我想写一个循环来计算我选择的范围内的矢量值的频率,这将包括具有0个频率的值 例如,如果我选择范围1:9,我的结果将是

3 2 1 0 0 1 0 1 2 

如果我选择1:11,结果将是

3 2 1 0 0 1 0 1 2 0 0

这可能吗?同样理想情况下,我必须为巨型矩阵和向量执行此操作,因此可以通过快速计算方法来理解这一点。

4 个答案:

答案 0 :(得分:4)

这是histcounts的另一个建议,在Matlab 2015b上看起来要快8倍:

A = [ 1 1 1 2 2 3 6 8 9 9 ];
maxRange = 11;
N = accumarray(A(:), 1, [maxRange,1])';
N =
     3     2     1     0     0     1     0     1     2     0     0

比较速度:

K>> tic; for i = 1:100000, N1 = accumarray(A(:), 1, [maxRange,1])'; end; toc;
Elapsed time is 0.537597 seconds.

K>> tic; for i = 1:100000, N2 = histcounts(A,1:maxRange+1); end; toc;
Elapsed time is 4.333394 seconds.

K>> isequal(N1, N2)
ans =
     1

答案 1 :(得分:2)

根据循环请求,这里是一个循环版本,自最近的引擎大修以来不应该太慢:

A = [ 1 1 1 2 2 3 6 8 9 9 ];
maxRange = 11; %// your range
output = zeros(1,maxRange); %// initialise output
for ii = 1:maxRange
    tmp = A==ii; %// temporary storage
    output(ii) = sum(tmp(:)); %// find the number of occurences
end

会导致

output = 
       3     2     1     0     0     1     0     1     2     0     0

使用@beaker's suggestion

时,histcounts更快且不循环
[N,edges] = histcounts(A,1:maxRange+1);
N =

     3     2     1     0     0     1     0     1     2     0

+1确保包含最后一个条目。

答案 2 :(得分:2)

假设输入A是一个排序数组,范围从1开始,直到某个值大于或等于A中的最大元素,这里'使用difffind -

的方法
%// Inputs
A = [2 4 4 4 8 9 11 11 11 12]; %// Modified for variety
maxN = 13;

idx = [0 find(diff(A)>0) numel(A)]+1;
out = zeros(1,maxN); %// OR for better performance : out(maxN) = 0;
out(A(idx(1:end-1))) = diff(idx);

输出 -

out =
     0     1     0     3     0     0     0     1     1     0     3     1     0

答案 3 :(得分:2)

使用bsxfun可以非常轻松地完成此操作。

让数据

A = [ 1 1 1 2 2 3 6 8 9 9 ]; %// data
B = 1:9; %// possible values

然后

result = sum(bsxfun(@eq, A(:), B(:).'), 1);

给出

result =
     3     2     1     0     0     1     0     1     2