Schnellster Weg, um eindeutige Werte in einem Array zu finden

8

Ich versuche einen schnellen Weg zu finden, um eindeutige Werte in einem Array zu finden und 0 als Möglichkeit für einen eindeutigen Wert zu entfernen.

Im Moment habe ich zwei Lösungen:

%Vor%

dataArray entspricht:

%Vor%

In diesem Fall ist result1 gleich [1; 2] und result2 ist gleich [0; 1; 2] . Die Funktion unique ist schneller, aber ich möchte nicht, dass 0 berücksichtigt wird. Gibt es eine Möglichkeit, dies mit unique zu tun und nicht 0 als eindeutigen Wert zu betrachten? Gibt es eine andere Alternative?

BEARBEITEN

Ich wollte die verschiedenen Lösungen zeitlich anpassen.

%Vor%

Und die Ergebnisse:

%Vor%

Die Lösung mit sparse und accumarray funktioniert jedoch nur mit integer . Diese Lösungen funktionieren nicht mit double .

    
m_power 18.12.2013, 20:28
quelle

4 Antworten

5

Hier ist ein verrückter Vorschlag mit accumarray , demonstriert mit Floris 'Testdaten:

%Vor%

Danke an Luis Mendo, der darauf hingewiesen hat, dass mit nonzeros result = result(result>0) ! nicht ausgeführt werden muss!

Beachten Sie, dass diese Lösung Daten mit ganzzahligen Werten benötigt (nicht unbedingt ein ganzzahliger Datentyp, sondern nur nicht mit dezimalen Komponenten). Das Vergleichen von Gleitkommawerten für die Gleichheit, wie es unique tun würde, ist gefährlich. Siehe hier und hier .

Ursprünglicher Vorschlag: Kombiniere unique mit setdiff :

%Vor%

Oder entfernen Sie mit der logischen Indizierung nach unique :

%Vor%

Im Allgemeinen bevorzuge ich die Zuweisung von [] in ( result(result==0)=[]; ), da es für große Datensätze sehr ineffizient wird.

Das Entfernen von Nullen nach unique sollte schneller sein, da es mit weniger Daten arbeitet (es sei denn, jedes Element ist eindeutig, ODER wenn a / dataArray sehr kurz ist).

    
chappjc 18.12.2013, 20:36
quelle
5

Um dem allgemeinen Lärm noch etwas hinzuzufügen - hier sind drei verschiedene Methoden. Sie alle geben die gleiche Antwort, aber etwas andere Zeiten:

%Vor%

Auf meinem Computer waren die Timings (für ein Array von 100000 Elementen) wie folgt:

%Vor%

Ich mag immer sparse für ein Problem wie dieses - Sie erhalten die Anzahl der Elemente gleichzeitig mit ihren eindeutigen Werten.

BEARBEITEN nach dem Vorschlag von @ chappj. Ich habe eine vierte Option hinzugefügt

%Vor%

Zeit:

%Vor%

Meine Damen und Herren, wir haben einen Gewinner.

AFTERWORD Die indexbasierten Methoden ( sparse und accumarray ) arbeiten nur mit Eingaben mit ganzzahligen Werten (obwohl sie vom Typ double sein können). Dies schien auf der Grundlage des in der Frage angegebenen Eingabearrays OK zu sein, funktioniert jedoch nicht bei nicht ganzzahligen Eingängen. Natürlich ist unique ein kniffliges Konzept, wenn man verdoppelt - die Zahl, die "gleich" aussieht, kann unterschiedlich dargestellt werden. Sie könnten das Eingabearray abschneiden (die Daten bereinigen), um sicherzustellen, dass dies kein Problem ist. Zum Beispiel, wenn Sie

getan haben %Vor%

Sie würden alle Werte auf nicht mehr als 3 signifikante Zahlen runden, und weil Sie "über ein int" gegangen sind, sind Sie sicher, dass Sie nicht mit Werten enden, die "sehr subtil verschieden" sind (sagen wir in der achten Ziffer) oder darüber hinaus). Natürlich könntest du in diesem Fall auch

machen %Vor%

Dies ist "ziemlich robust" für nicht ganzzahlige Werte (im obigen Fall behandelt es Werte mit bis zu drei signifikanten Stellen; wenn Sie mehr benötigen, wird der Platzbedarf irgendwann zu groß und diese Methode wird langsamer als unique , welches die Daten tatsächlich sortieren muss.)

    
Floris 18.12.2013 20:51
quelle
3

Warum nicht die Nullen als zweiten Schritt entfernen:

%Vor%     
Pursuit 18.12.2013 20:35
quelle
0

Ich habe auch einen anderen Weg gefunden:

%Vor%     
m_power 18.12.2013 20:43
quelle

Tags und Links