Ich suche nach dem schnellsten Weg, um das Auftreten von NaN ( np.nan
) in einem NumPy-Array zu überprüfen X
. np.isnan(X)
kommt nicht in Frage, da es ein boolesches Array von Formen bildet X.shape
, das möglicherweise gigantisch ist.
Ich habe es versucht np.nan in X
, aber das scheint nicht zu funktionieren, weil np.nan != np.nan
. Gibt es eine schnelle und speichereffiziente Möglichkeit, dies überhaupt zu tun?
(Für diejenigen, die fragen würden, "wie gigantisch": Ich kann es nicht sagen. Dies ist eine Eingabevalidierung für den Bibliothekscode.)
scipy.sparse
-Matrizen als Eingabe.Antworten:
Rays Lösung ist gut. Allerdings auf meiner Maschine handelt es sich um 2,5 - fach schneller verwenden
numpy.sum
anstelle vonnumpy.min
:Im Gegensatz dazu
min
istsum
keine Verzweigung erforderlich, was auf moderner Hardware eher teuer ist. Dies ist wahrscheinlich der Grund, warumsum
es schneller geht.Bearbeiten Der obige Test wurde mit einem einzigen NaN direkt in der Mitte des Feldes durchgeführt.
Es ist interessant festzustellen, dass dies
min
in Gegenwart von NaN langsamer ist als in Abwesenheit. Es scheint auch langsamer zu werden, wenn sich NaNs dem Anfang des Arrays nähern. Andererseitssum
scheint der Durchsatz konstant zu sein, unabhängig davon, ob es NaNs gibt und wo sie sich befinden:quelle
np.min
ist schneller, wenn das Array keine NaNs enthält, was meine erwartete Eingabe ist. Aber ich habe beschlossen, dieses trotzdem zu akzeptieren, weil es fängtinf
undneginf
auch.inf
oder-inf
wenn die Eingabe beide enthält, und es gibt Probleme, wenn die Eingabe große, aber endliche Werte enthält, die beim Addieren überlaufen.np.sum
immer noch etwa 30% schneller alsnp.min
.np.isnan(x).any(0)
ist etwas schneller alsnp.sum
undnp.min
auf meinem Computer, obwohl es möglicherweise zu unerwünschtem Caching kommt.Ich denke
np.isnan(np.min(X))
sollte tun was du willst.quelle
Auch wenn es eine akzeptierte Antwort gibt, möchte ich Folgendes demonstrieren (mit Python 2.7.2 und Numpy 1.6.0 unter Vista):
Daher kann der wirklich effiziente Weg stark vom Betriebssystem abhängen. Auf jeden
dot(.)
Fall scheint die Basis die stabilste zu sein.quelle
x
große Werte enthält, und ich möchte auch nach Informationen suchen.isfinite(.)
. Ich wollte nur auf die enorme Leistungslücke hinweisen. Dankemin
- odersum
-basierten Ansätze, die auf einen einzelnen Kern beschränkt sind. Ergo, diese Leistungslücke.Hier gibt es zwei allgemeine Ansätze:
nan
und nehmen Sieany
.nan
s (likesum
) erhalten bleibt, und überprüfen Sie das Ergebnis.Während der erste Ansatz sicherlich der sauberste ist, kann die starke Optimierung einiger der kumulativen Operationen (insbesondere derjenigen, die wie in BLAS ausgeführt werden
dot
) diese recht schnell machen. Beachten Sie, dassdot
wie bei einigen anderen BLAS-Operationen unter bestimmten Bedingungen Multithreading ausgeführt wird. Dies erklärt den Geschwindigkeitsunterschied zwischen verschiedenen Maschinen.quelle
benutze .any ()
if numpy.isnan(myarray).any()
numpy.isfinite vielleicht besser als isnan für die Überprüfung
if not np.isfinite(prop).all()
quelle
Wenn Sie sich wohl fühlen numba Es ermöglicht die Erzeugung eines schnellen Kurzschlusses (stoppt, sobald ein NaN gefunden wird):
Wenn dies nicht
NaN
der Fall ist, ist die Funktion möglicherweise langsamer alsnp.min
. Ich denke, das liegt daran, dassnp.min
Multiprocessing für große Arrays verwendet wird:Wenn sich jedoch ein NaN im Array befindet, insbesondere wenn seine Position bei niedrigen Indizes liegt, ist es viel schneller:
Ähnliche Ergebnisse können mit Cython oder einer C-Erweiterung erzielt werden. Diese sind etwas komplizierter (oder leicht verfügbar als
bottleneck.anynan
), tun aber letztendlich das Gleiche wie meineanynan
Funktion.quelle
Damit verbunden ist die Frage, wie das erste Auftreten von NaN gefunden werden kann. Dies ist der schnellste Weg, um mit dem umzugehen, von dem ich weiß:
quelle