Skuteczne sprawdzanie, czy dowolny obiekt to NaN w Pythonie / numpy / pandas?

101

Moje tablice numpy używają np.nando oznaczania brakujących wartości. Podczas iteracji zestawu danych muszę wykrywać takie brakujące wartości i traktować je w specjalny sposób.

Naiwnie użyłem numpy.isnan(val), co działa dobrze, chyba że valnie jest wśród podzbioru typów obsługiwanych przez numpy.isnan(). Na przykład brakujące dane mogą wystąpić w polach ciągów, w takim przypadku otrzymuję:

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

Czy poza napisaniem drogiego opakowania, które wyłapuje wyjątek i zwraca False, istnieje sposób, aby poradzić sobie z tym elegancko i wydajnie?

Dun Peal
źródło
8
pandashas pandas.isnull(): Nie jestem pewien, czy to spełnia Twoje potrzeby, więc niektóre przykładowe dane mogą być dobre.
Marius,
4
@Marius: pandas.isnull()wydaje się działać idealnie. Jedynym typem danych, z którym obecnie mam do czynienia, a którym są podziały, numpy.isnan()jest ciąg i pandas.isnull()dobrze go obsługuje. W rzeczywistości wydaje się, że dobrze radzi sobie z każdym przypadkowym przedmiotem, który w niego rzuciłem. Czy były jakieś konkretne problemy, którymi się martwiłeś? W przeciwnym razie możesz przesłać komentarz jako pełną odpowiedź, ponieważ wydaje się, że jest to odpowiedź kanoniczna, przynajmniej dla użytkowników pand.
Dun Peal,

Odpowiedzi:

169

pandas.isnull()(również pd.isna()w nowszych wersjach) sprawdza brakujące wartości zarówno w tablicach liczbowych, jak i ciągów / obiektów. Na podstawie dokumentacji sprawdza:

NaN w tablicach numerycznych, None / NaN w tablicach obiektów

Szybki przykład:

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

Pomysł użycia numpy.nando reprezentowania brakujących wartości jest czymś, co pandaswprowadziło, dlatego pandasma narzędzia do radzenia sobie z tym.

Czasy danych też (jeśli używasz pd.NaT, nie musisz określać 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
źródło
19

Czy twój typ jest naprawdę dowolny? Jeśli wiesz, że będzie to po prostu int float lub string, możesz to zrobić

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

zakładając, że jest opakowany w numpy, zawsze będzie miał dtype i tylko zmiennoprzecinkowe i złożone mogą być NaN

Młotek
źródło
Mam do czynienia z wieloma różnymi rodzajami danych. Podczas gdy większość kolumn ma typy danych int * lub float *, inne mogą być dowolnymi obiektami, chociaż do tej pory jedynym innym typem, którego użyłem, był łańcuch.
Dun Peal
Ciągi znaków w Pythonie nie mają dtype. Być może będziesz musiał to zrobićtype(val) == 'float'
pvarma
4
type(val) == float and np.isnan(val)- pracował dla mnie
Danny Cullen
@ user1930402 Zakładam, że są to tablice numpy, a nie zwykłe tablice Pythona. Na przykład: np.array (["hello"]) [0] .dtype działa, ale ["hello"] [0] .dtype nie
Hammer