Wie kann man effizient prüfen, ob eine Matrix binär ist (z. B. alle 1 oder 0)?

8

Ich habe eine Funktion, die eine mx n große (potentiell) binäre Matrix als Eingabe nimmt, und ich möchte eine Fehlerbehandlung zurückgeben, wenn die Matrix eine Zahl enthält, die nicht 0 oder 1 ist, oder NA ist. Wie kann ich das effizient überprüfen?

Zum Beispiel, indem einige Daten für ein 10 x 10 erzeugt werden:

%Vor%

sollte immer zurückgeben, dass die Matrix binär ist, aber sie auf eine der folgenden Weisen ändern:

%Vor%

sollte zurückgeben, dass die Matrix nicht binär ist.

Zur Zeit habe ich in meiner Funktion verwendet:

%Vor%

Es scheint aber sehr langsam und ineffizient zu sein, jeden Wert für große Matrizen individuell zu prüfen. Gibt es einen cleveren, einfachen Weg, den ich vermisse?

Danke

    
Csislander 24.04.2014, 16:06
quelle

5 Antworten

5

Ich dachte sofort an identical(mat,matrix(as.numeric(as.logical(mat),nr=nrow(mat)) ) )

Damit bleibt NA als NA . Wenn Sie also die Existenz eines solchen suchen möchten, benötigen Sie nur einen schnellen any(is.na(mat)) oder einen ähnlichen Test.

EDIT: Zeitfahren

%Vor%

Und gegen das not... -Ding: Ich musste einen try einwerfen, um den Test nicht zu unterbrechen.

%Vor%

Ich gewinne! : -)

    
Carl Witthoft 24.04.2014, 17:40
quelle
5

Hier sind die Zeitangaben für einige Optionen (einschließlich Optionen, die in anderen Antworten vorgeschlagen werden):

%Vor%

Sie sind alle ziemlich schnell, wenn man bedenkt, dass es eine Matrix von 5000 mal 5000 ist! Der schnellste der drei scheint zu sein:

%Vor%     
James Trimble 24.04.2014 16:25
quelle
4

Ich möchte eine leicht modifizierte Version des sum basierten Vergleichs hinzufügen, die schneller ist als @ JamesTrimbles Version. Ich hoffe, dass alle meine Annahmen richtig sind:

%Vor%

Hier der Maßstab:

%Vor%     
sgibb 24.04.2014 16:56
quelle
3

Ein ziemlich effizienter (und lesbarer ) Weg könnte sein

%Vor%

Wie bereits erwähnt, ist es im Vergleich zu anderen Lösungen möglicherweise nicht die schnellste Methode.

Aber, um ein paar hinzuzufügen, wenn Effizienz ist ein Muss (zB Sie diesen Test viel tun von Zeiten) eine viel Gewinn wird durch die Arbeit mit integer Matrix gegeben ( double s haben mehr Bytes) und überprüfen Sie gegen integer -Werte. Dieser Vorteil könnte auch für andere Lösungen gelten. Ein paar Tests mit %in% folgen:

%Vor%

Von 3.70 bis 1.32 ist nicht so schlimm:)

    
Luca Braglia 24.04.2014 16:20
quelle
1

Beachten Sie, dass ich ein paar Dinge geändert habe, so dass es in octave läuft, aber es sollte ziemlich ähnlich zu matlab sein.

Generiere die Matrix:

%Vor%

Jetzt machen wir einfach etwas Einfaches, wir wissen, dass 1*2-1 1 gleich 1 macht, während 0 gleich -1 ist. Also macht abs alles gleich. Für jeden anderen Wert, sagen wir -1 , -1*2-1=-3 , ist dies nicht der Fall. Dann subtrahieren wir 1 und es sollte eine Matrix mit nur Nullen übrigbleiben. Dies kann einfach in Matlab / Octave mit any :

überprüft werden %Vor%

Überprüfen Sie die Geschwindigkeit:

%Vor%

In der Reihenfolge total , user und system time.

Sehr schön unter 0.18 Sekunden mit den meisten davon im Benutzermodus. Mit 10.000 * 10.000 Einträgen ist es immer noch unter einer Sekunde, in 0.86 Sekunden auf meinem System eintaktig.

Oh, hey, ich sehe nur, dass es tatsächlich nach R gefragt wird, nicht nach matlab . Ich hoffe, dass jemand den Vergleich mag.

Die Verarbeitung von NaN -Werten ist einfach in octave / matlab mit isnan(mat) , eventuell in Form von any(any(isnan(mat))) , wenn Sie möchten. Dies beinhaltet NA -Werte. Die Verarbeitung von NA -Werten erfolgt nur über isna(mat) .

    
Anne van Rossum 24.04.2014 23:30
quelle

Tags und Links