2014-02-11 7 views
7

Was ist der schnellste Weg, ein Array A zu nehmen und beide auszugeben [d. H. der Satz von einzigartigen Array-Elementen von A] sowie das Multiplizitäts-Array, das an seiner i-ten Stelle die i-te Multiplizität des i-ten Eintrags von in A aufnimmt.Wie man schnell das Array von Multiplizitäten erhält

Das ist ein Bissen, also hier ein Beispiel. Gegeben A=[1 1 3 1 4 5 3], ich will:

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

Dies kann für Schleife mit einem mühsam durchgeführt werden, würde aber gerne wissen, ob es einen Weg gibt, um das Array Art von MATLAB zu nutzen .

Antwort

7
uA = unique(A); 
mult = histc(A,uA); 

Alternativ:

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

Benchmarking

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 

Ergebnisse mit N = 100:

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

Ergebnisse mit N = 1000:

Elapsed time is 0.481456 seconds. 
Elapsed time is 4.534572 seconds. 
Elapsed time is 0.550606 seconds. 
+0

Haben Sie eine Meinung haben zu, die von denen zwei schneller ist? – Lepidopterist

+0

@GregorianFunk Ich weiß es nicht ... Es kann auch auf die Größe von 'A' abhängen. Manchmal ist eine Lösung für kleine Größen am schnellsten, aber nicht für große. Probieren Sie es aus! –

+1

@GregorianFunk Ich habe ein paar Tests gemacht (siehe bearbeitete Antwort). Der erste ist deutlich schneller. Die Antwort von chappjc ist sehr nahe –

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

accumarray ist sehr schnell. Leider wird unique langsam mit 3 Ausgängen.


späte Zugabe:

uA = unique(A); 
mult = nonzeros(accumarray(A(:),1,[],@sum,0,true)) 
2
S = sparse(A,1,1); 
[uA,~,mult] = find(S); 

ich diese elegante Lösung in an old Newsgroup thread gefunden habe.

Testen mit dem benchmark of Luis Mendo für N = 1000:

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

(Auf meinem Rechner accumarray Ergebnisse in Error: Maximum variable size allowed by the program is exceeded.)

Verwandte Themen