Verificar com eficiência se o objeto arbitrário é NaN em Python / numpy / pandas?

101

Minhas matrizes numpy usam np.nanpara designar valores ausentes. À medida que faço a iteração no conjunto de dados, preciso detectar esses valores ausentes e tratá-los de maneiras especiais.

Usei ingenuamente numpy.isnan(val), o que funciona bem, a menos que valnão esteja entre o subconjunto de tipos suportados por numpy.isnan(). Por exemplo, dados ausentes podem ocorrer em campos de string, caso em que recebo:

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

Além de escrever um invólucro caro que captura a exceção e retorna False, há uma maneira de lidar com isso de maneira elegante e eficiente?

Dun Peal
fonte
8
pandastem pandas.isnull(): Não tenho certeza se isso atende às suas necessidades, portanto, alguns dados de exemplo podem ser bons.
Marius,
4
@Marius: pandas.isnull()parece funcionar perfeitamente. O único tipo de dados com o qual estou lidando atualmente com quebras numpy.isnan()é string, e pandas.isnull()lida bem com isso. Na verdade, ele parece lidar bem com qualquer objeto arbitrário que eu joguei nele. Você estava preocupado com algum problema específico? Caso contrário, você pode querer enviar seu comentário como uma resposta completa, já que parece uma resposta canônica, pelo menos para usuários de pandas.
Dun Peal

Respostas:

169

pandas.isnull()(também pd.isna(), em versões mais recentes) verifica se há valores ausentes em matrizes numéricas e de string / objeto. Na documentação, ele verifica:

NaN em matrizes numéricas, Nenhum / NaN em matrizes de objetos

Exemplo 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

A ideia de usar numpy.nanpara representar valores ausentes é algo que pandasintroduzimos, por isso pandastem as ferramentas para lidar com isso.

Datetimes também (se você usar pd.NaT, não será necessário especificar o dtype)

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
fonte
19

Seu tipo é realmente arbitrário? Se você sabe que será apenas um float interno ou string, você pode simplesmente fazer

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

assumindo que está envolvido em numpy, sempre terá um tipo d e apenas flutuante e complexo podem ser NaN

Martelo
fonte
Estou lidando com muitos tipos diferentes de dados. Enquanto a maioria das colunas tem tipos de dados int * ou float *, outras podem ser qualquer objeto, embora até agora o único outro tipo que usei foi string.
Dun Peal
Strings em python não tem dtype. Você pode ter que fazertype(val) == 'float'
pvarma
4
type(val) == float and np.isnan(val)- trabalhou para mim
Danny Cullen
@ user1930402 Estou assumindo que esses são arrays entorpecidos, não os normais do Python. Por exemplo: np.array (["hello"]) [0] .dtype funciona, mas ["hello"] [0] .dtype não
Hammer