¿Comprobando eficientemente si el objeto arbitrario es NaN en Python / numpy / pandas?

101

Mis matrices numpy se utilizan np.nanpara designar valores faltantes. A medida que repito el conjunto de datos, necesito detectar esos valores faltantes y manejarlos de formas especiales.

Usé ingenuamente numpy.isnan(val), que funciona bien a menos valque no esté entre el subconjunto de tipos admitidos por numpy.isnan(). Por ejemplo, los datos faltantes pueden ocurrir en campos de cadena, en cuyo caso obtengo:

>>> np.isnan('some_string')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Not implemented for this type

Aparte de escribir un contenedor costoso que detecta la excepción y devuelve False, ¿hay alguna manera de manejar esto de manera elegante y eficiente?

Dun Peal
fuente
8
pandastiene pandas.isnull(): no estoy seguro de si eso satisface sus necesidades, por lo que algunos datos de ejemplo podrían ser buenos.
Marius
4
@Marius: pandas.isnull()parece funcionar perfectamente. El único tipo de datos con el que estoy tratando actualmente que se rompe numpy.isnan()es la cadena y lo pandas.isnull()maneja bien. De hecho, parece manejar bien cualquier objeto arbitrario que le arroje. ¿Hubo algún problema específico que le preocupara? De lo contrario, es posible que desee enviar su comentario como una respuesta completa, ya que parece la respuesta canónica, al menos para los usuarios de pandas.
Dun Peal

Respuestas:

169

pandas.isnull()(también pd.isna(), en versiones más recientes) comprueba los valores perdidos en matrices numéricas y de cadena / objeto. De la documentación, busca:

NaN en matrices numéricas, Ninguno / NaN en matrices de objetos

Ejemplo rápido:

import pandas as pd
import numpy as np
s = pd.Series(['apple', np.nan, 'banana'])
pd.isnull(s)
Out[9]: 
0    False
1     True
2    False
dtype: bool

La idea de usar numpy.nanpara representar valores perdidos es algo que pandasintrodujo, por eso pandastiene las herramientas para lidiar con ello.

Las fechas también (si las usa pd.NaT, no necesitará especificar el tipo d)

In [24]: s = Series([Timestamp('20130101'),np.nan,Timestamp('20130102 9:30')],dtype='M8[ns]')

In [25]: s
Out[25]: 
0   2013-01-01 00:00:00
1                   NaT
2   2013-01-02 09:30:00
dtype: datetime64[ns]``

In [26]: pd.isnull(s)
Out[26]: 
0    False
1     True
2    False
dtype: bool
Marius
fuente
19

¿Es tu tipo realmente arbitrario? Si sabe que solo será un flotador o una cadena int, podría hacer

 if val.dtype == float and np.isnan(val):

asumiendo que está envuelto en numpy, siempre tendrá un dtype y solo float y complex pueden ser NaN

Martillo
fuente
Estoy tratando con muchos tipos diferentes de datos. Si bien la mayoría de las columnas tienen tipos de datos int * o float *, otras podrían ser cualquier objeto, aunque hasta ahora el único otro tipo que usé fue string.
Dun Peal
Las cadenas en Python no tienen dtype. Puede que tengas que hacerlotype(val) == 'float'
pvarma
4
type(val) == float and np.isnan(val)- funcionó para mí
Danny Cullen
@ user1930402 Supongo que se trata de matrices numerosas, no de Python normales. Por ejemplo: np.array (["hello"]) [0] .dtype funciona pero ["hello"] [0] .dtype no
Hammer