Как быстро получить массив кратностей

Какой самый быстрый способ взять массив A и выводит оба unique(A) [т.е. набор уникальных элементов массива A], а также массив множественности, который занимает i-е место i-й кратности i-й записи unique(A) в A,

Это полный рот, так что вот пример. Дано A=[1 1 3 1 4 5 3], Я хочу:

  1. unique(A)=[1 3 4 5]
  2. mult = [3 2 1 1]

Это можно сделать с помощью утомительного цикла for, но хотелось бы знать, есть ли способ использовать массивность MATLAB.

3 ответа

Решение
uA = unique(A);
mult = histc(A,uA);

В качестве альтернативы:

uA = unique(A);
mult = sum(bsxfun(@eq, uA(:).', A(:)));

Бенчмаркинг

N = 100;
A = randi(N,1,2*N); %// size 1 x 2*N

%// Luis Mendo, first approach
tic
for iter = 1:1e3;
    uA = unique(A);
    mult = histc(A,uA);
end
toc

%// Luis Mendo, second approach    
tic
for iter = 1:1e3;
    uA = unique(A);
    mult = sum(bsxfun(@eq, uA(:).', A(:)));
end
toc

%'// chappjc
tic
for iter = 1:1e3;
    [uA,~,ic] = unique(A);    % uA(ic) == A
    mult= accumarray(ic.',1);
end
toc

Результаты с N = 100:

Elapsed time is 0.096206 seconds.
Elapsed time is 0.235686 seconds.
Elapsed time is 0.154150 seconds.

Результаты с N = 1000:

Elapsed time is 0.481456 seconds.
Elapsed time is 4.534572 seconds.
Elapsed time is 0.550606 seconds.
S = sparse(A,1,1);
[uA,~,mult] = find(S);

Я нашел это элегантное решение в старой ветке новостной группы.

Тестирование с тестом Луиса Мендо для N = 1000:

Elapsed time is 0.228704 seconds. % histc
Elapsed time is 1.838388 seconds. % bsxfun
Elapsed time is 0.128791 seconds. % sparse

(На моей машине, accumarray результаты в Error: Maximum variable size allowed by the program is exceeded.)

[uA,~,ic] = unique(A);    % uA(ic) == A
mult = accumarray(ic.',1);

accumarray очень быстро К несчастью, unique становится медленным с 3 выходами.


Позднее добавление:

uA = unique(A);
mult = nonzeros(accumarray(A(:),1,[],@sum,0,true))
Другие вопросы по тегам