Ich versuche, eine Art Interpolationsalgorithmus zu implementieren. I
ist eine N * 4-Matrix, die Indizes von umgebenden Punkten von N
anderen Punkten enthält. Elemente in jeder Zeile von I
dürfen jedoch nicht eindeutig sein, dh zwei oder mehr von ihnen können sich auf einen einzelnen Punkt beziehen. Ich möchte wissen, wie viele eindeutige Indizes in jeder Zeile verfügbar sind, und ich möchte es so schnell wie möglich tun, da N
groß ist!Wie finde ich die Anzahl der einzigartigen Elemente in jeder Zeile einer Matrix?
Antwort
Nun, Mohsen's answer ist eine allgemeine Lösung für dieses Problem, aber arrayfun
war zu langsam für mich. Also habe ich ein wenig mehr darüber nachgedacht und eine viel schnellere Lösung gefunden. Ich vergleiche alle Paare von Spalten und einen Zähler erhöhen, wenn sie gleich waren:
tic;
S = zeros(N, 1, 'uint32');
Nu = S+4; % in my case most of point are surrounded by four different points
for i=1:3
for j=(i+1):4
S = S + uint32(I(:, i)==I(:, j));
end
end
% Nu(S==0) = 4;
Nu(S==1) = 3;
Nu((S==2)|(S==3)) = 2; % why? :)
Nu(S==6) = 1;
toc;
Für N=189225
, arrayfun
14.73s auf meinem PC nimmt aber Summierung dauert nur 0,04s.
Edit: Achten Sie auf eine unterschiedliche Anzahl von Spalten
Hier ist eine Modifikation des Codes oben. Jetzt können wir auch die Plätze der einzigartigen Werte in jeder Reihe haben! Dieser hat nicht das :)
Problem und kann für höhere Anzahlen der Spalten benutzt werden. Immer noch 0,04s auf meinem PC für 189225 Reihen.
tic;
uniq = true(N, 4);
for i=1:3
for j=(i+1):4
uniq(I(:, i)==I(:, j), j) = false;
end
end
Nu = sum(uniq, 2);
toc;
Edit (2): Der Vergleich mit EBH ‚s answer
Nach einer Weile habe ich dies für ein anderes Problem benötigt, wo ich Anzahl der einzelnen Elemente in jeder Reihe von Matrizen mit einer unterschiedlichen Anzahl von Spalten gesucht . Also habe ich meinen Code mit EBH verglichen, um zu sehen, ob ihr Code schneller ist. Ich lief beide Codes auf Matrizen mit Reihen von 10K bis 100K und Spalten von 6 bis 60. Die Ergebnisse sind durchschnittlich verbrachte Zeit (in Sekunden) von 3 verschiedenen Läufen:
Ich teste diese in 2016a und es gab eine signifikante Verbesserung der Leistung von FOR-Schleifen in den neuesten Versionen von MATLAB. Möglicherweise müssen Sie es also selbst vergleichen, wenn Sie es in älteren Versionen ausführen möchten.
Sie müssen unique
Funktion in jeder Zeile verwenden und die Elemente des Ergebnisses zählen:
arrayfun(@(x) numel(unique(I(x,:))), (1:size(I,1)).')
Die Indexanordnung umgesetzt wird, so dass das Ergebnis ein Spaltenvektor ist.
Hier ist eine super schnelle Art und Weise, ohne Schleifen zu tun:
accumarray(repmat(1:size(I,1),1,size(I,2)).',I(:),[],@(x) numel(unique(x)))
Dies wird Ihnen eine Vektorgröße N, wobei das Element anstelle k die Anzahl der eindeutigen Elemente in I(k,:)
ist.
Würden Sie bitte meine Antwort überprüfen. mamnoon misham;) – saastn
Wie bearbeite ich die obige Syntax, damit Nullen nicht als eindeutiges Element berücksichtigt werden? – Sade
ändere 'unique (I (x, :)) 'in' setdiff (I (x, :), 0) ' –