Contando el número de elementos que no son NaN en un ndarray numpy en Python

Necesito calcular el número de elementos que no son NaN en una matriz de ndarray numpy. ¿Cómo se haría esto de manera eficiente en Python? Aquí está mi código simple para lograr esto:

import numpy as np def numberOfNonNans(data): count = 0 for i in data: if not np.isnan(i): count += 1 return count 

¿Hay una función incorporada para esto en numpy? La eficiencia es importante porque estoy haciendo un análisis de Big Data.

Gracias por cualquier ayuda!

 np.count_nonzero(~np.isnan(data)) 

~ invierte la matriz booleana devuelta desde np.isnan .

np.count_nonzero cuenta valores que no son 0 \ false. .sum debe dar el mismo resultado. Pero tal vez sea más claro usar count_nonzero

Velocidad de prueba:

 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)) parece ser apenas el más rápido aquí. Otros datos pueden dar diferentes resultados de velocidad relativa.

Alterante de escritura rápida

Aunque no es la opción más rápida, si el rendimiento no es un problema, puede usar:

sum(~np.isnan(data)) .

Actuación:

 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 

Una alternativa, pero una alternativa un poco más lenta es hacerlo sobre la indexación.

 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 

El doble uso de np.isnan(data) y el operador == puede ser un poco excesivo, por lo que publiqué la respuesta solo para completarla.

Para determinar si la matriz es escasa, puede ser útil obtener una proporción de valores nanométricos

 np.isnan(ndarr).sum() / ndarr.size 

Si esa proporción supera un umbral, use una matriz dispersa, por ejemplo, https://sparse.pydata.org/en/latest/