Estoy buscando la forma más rápida de verificar la aparición de NaN ( np.nan) en una matriz NumPy X. np.isnan(X)está fuera de discusión, ya que crea una matriz booleana de formas X.shape, que es potencialmente gigantesca.
Lo intenté np.nan in X, pero eso parece no funcionar porque np.nan != np.nan. ¿Existe alguna forma rápida y eficiente en memoria de hacer esto?
(Para aquellos que preguntan "cuán gigantesco": no puedo decirlo. Esta es la validación de entrada para el código de la biblioteca).

scipy.sparsematrices NumPy como entrada.Respuestas:
La solución de Ray es buena. Sin embargo, en mi máquina es aproximadamente 2.5 veces más rápido de usar
numpy.sumen lugar denumpy.min:A diferencia
min,sumno requiere ramificación, que en el hardware moderno tiende a ser bastante caro. Esta es probablemente la razón por la quesumes más rápido.editar La prueba anterior se realizó con un solo NaN justo en el medio de la matriz.
Es interesante notar que
mines más lento en presencia de NaN que en su ausencia. También parece volverse más lento a medida que los NaN se acercan al inicio de la matriz. Por otro lado,sumel rendimiento parece constante independientemente de si hay NaN y dónde se encuentran:fuente
np.mines más rápido cuando la matriz no contiene NaN, que es mi entrada esperada. Pero he decidido aceptar este de todos modos, porque atrapainfyneginftambién.info-infsi la entrada contiene ambos, y tiene problemas si la entrada contiene valores grandes pero finitos que se desbordan cuando se suman.np.sumsigue siendo un 30% más rápido quenp.min.np.isnan(x).any(0)es un poco más rápido quenp.sumynp.minen mi máquina, aunque puede haber algún almacenamiento en caché no deseado.Creo que
np.isnan(np.min(X))debería hacer lo que quiera.fuente
Incluso si existe una respuesta aceptada, me gustaría demostrar lo siguiente (con Python 2.7.2 y Numpy 1.6.0 en Vista):
Por lo tanto, la forma realmente eficiente podría depender en gran medida del sistema operativo. De todos modos el
dot(.)basado parece ser el más estable.fuente
xcontiene valores grandes, y también quiero verificar inf.isfinite(.). Solo quería señalar la enorme brecha de rendimiento. Graciasmin- osumenfoques basados, que se ejecutan confinadas a un solo núcleo. Ergo, esa brecha de desempeño.Aquí hay dos enfoques generales:
nany tómeloany.nans (likesum) y verifique su resultado.Si bien el primer enfoque es ciertamente el más limpio, la gran optimización de algunas de las operaciones acumulativas (particularmente las que se ejecutan en BLAS, como
dot) puede hacerlas bastante rápidas. Tenga en cuenta quedot, al igual que algunas otras operaciones BLAS, son multiproceso en determinadas condiciones. Esto explica la diferencia de velocidad entre diferentes máquinas.fuente
usar cualquier()
if numpy.isnan(myarray).any()numpy.isfinite quizás mejor que isnan para comprobar
if not np.isfinite(prop).all()fuente
Si te sientes cómodo con numba permite crear un cortocircuito rápido (se detiene tan pronto como se encuentra un NaN) función:
Si no hay,
NaNla función podría ser más lenta quenp.min, creo que se debe a quenp.minusa multiprocesamiento para matrices grandes:Pero en caso de que haya un NaN en la matriz, especialmente si su posición está en índices bajos, entonces es mucho más rápido:
Se pueden lograr resultados similares con Cython o una extensión de C, estos son un poco más complicados (o fácilmente disponibles como
bottleneck.anynan) pero en última instancia hacen lo mismo que mianynanfunción.fuente
Relacionado con esto está la cuestión de cómo encontrar la primera aparición de NaN. Esta es la forma más rápida de manejar eso que conozco:
fuente