Ich muss die Anzahl der Nicht-NaN-Elemente in einer Numpy-Ndarray-Matrix berechnen. Wie würde man das in Python effizient machen? Hier ist mein einfacher Code, um dies zu erreichen:
import numpy as np
def numberOfNonNans(data):
count = 0
for i in data:
if not np.isnan(i):
count += 1
return count
Gibt es dafür eine eingebaute Funktion in numpy? Effizienz ist wichtig, weil ich Big Data-Analysen durchführe.
Danke für jede Hilfe!
sum(not np.isnan(x) for x in a)
, aber in Bezug auf die Geschwindigkeit ist sie langsam im Vergleich zur @ M4rtini-Numpy-Version.Antworten:
~
invertiert die von zurückgegebene boolesche Matrixnp.isnan
.np.count_nonzero
zählt Werte, die nicht 0 \ false sind..sum
sollte das gleiche Ergebnis geben. Aber vielleicht klarer zu bedienencount_nonzero
Testgeschwindigkeit:
In [23]: data = np.random.random((10000,10000)) In [24]: data[[np.random.random_integers(0,10000, 100)],:][:, [np.random.random_integers(0,99, 100)]] = np.nan In [25]: %timeit data.size - np.count_nonzero(np.isnan(data)) 1 loops, best of 3: 309 ms per loop In [26]: %timeit np.count_nonzero(~np.isnan(data)) 1 loops, best of 3: 345 ms per loop In [27]: %timeit data.size - np.isnan(data).sum() 1 loops, best of 3: 339 ms per loop
data.size - np.count_nonzero(np.isnan(data))
scheint hier kaum der schnellste zu sein. Andere Daten können zu unterschiedlichen Ergebnissen der relativen Geschwindigkeit führen.quelle
numpy.isnan(array).sum()
? Ich bin allerdings nicht sehr gut mit Numpy.data.size - np.isnan(data).sum()
wird etwas effizienter sein.Schnell zu schreibende Alternative
Auch wenn dies nicht die schnellste Wahl ist, können Sie Folgendes verwenden, wenn die Leistung kein Problem darstellt:
sum(~np.isnan(data))
.Performance:
In [7]: %timeit data.size - np.count_nonzero(np.isnan(data)) 10 loops, best of 3: 67.5 ms per loop In [8]: %timeit sum(~np.isnan(data)) 10 loops, best of 3: 154 ms per loop In [9]: %timeit np.sum(~np.isnan(data)) 10 loops, best of 3: 140 ms per loop
quelle
len
stattdessen verwenden.Eine Alternative, aber etwas langsamer, ist die Indizierung.
np.isnan(data)[np.isnan(data) == False].size In [30]: %timeit np.isnan(data)[np.isnan(data) == False].size 1 loops, best of 3: 498 ms per loop
Die doppelte Verwendung von
np.isnan(data)
und der==
Operator könnten etwas übertrieben sein, und deshalb habe ich die Antwort nur der Vollständigkeit halber veröffentlicht.quelle
Um festzustellen, ob das Array dünn ist, kann es hilfreich sein, einen Anteil der Nanowerte zu erhalten
np.isnan(ndarr).sum() / ndarr.size
Wenn dieser Anteil einen Schwellenwert überschreitet, verwenden Sie ein spärliches Array, z. B. - https://sparse.pydata.org/en/latest/
quelle