Vérifier efficacement si l'objet arbitraire est NaN dans Python / numpy / pandas?

101

Mes tableaux numpy utilisent np.nanpour désigner les valeurs manquantes. En parcourant l'ensemble de données, je dois détecter ces valeurs manquantes et les gérer de manière spéciale.

J'ai utilisé naïvement numpy.isnan(val), ce qui fonctionne bien sauf s'il valne fait pas partie du sous-ensemble de types pris en charge par numpy.isnan(). Par exemple, des données manquantes peuvent se produire dans des champs de chaîne, auquel cas j'obtiens:

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

Outre l'écriture d'un wrapper coûteux qui détecte l'exception et renvoie False, existe-t-il un moyen de gérer cela de manière élégante et efficace?

Dun Peal
la source
8
pandashas pandas.isnull(): Je ne sais pas si cela répond à vos besoins, donc quelques exemples de données pourraient être utiles.
Marius
4
@Marius: pandas.isnull()semble fonctionner parfaitement. Le seul type de données auquel je suis actuellement confronté numpy.isnan()est une chaîne et la pandas.isnull()gère bien. En fait, il semble bien gérer tous les objets arbitraires que je lui ai lancés. Y avait-il des problèmes spécifiques qui vous préoccupaient? Sinon, vous voudrez peut-être soumettre votre commentaire en tant que réponse à part entière, car cela semble être la réponse canonique, du moins pour les utilisateurs de pandas.
Dun Peal

Réponses:

169

pandas.isnull()(également pd.isna(), dans les versions plus récentes) vérifie les valeurs manquantes dans les tableaux numériques et chaînes / objets. À partir de la documentation, il vérifie:

NaN dans les tableaux numériques, None / NaN dans les tableaux d'objets

Exemple rapide:

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

L'idée d'utiliser numpy.nanpour représenter les valeurs manquantes est quelque chose qui a pandasintroduit, c'est pourquoi il pandasa les outils pour y faire face.

Datetimes aussi (si vous utilisez, pd.NaTvous n'aurez pas besoin de spécifier le 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
la source
19

Votre type est-il vraiment arbitraire? Si vous savez que ce sera juste un flotteur int ou une chaîne, vous pouvez simplement le faire

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

en supposant qu'il est enveloppé dans numpy, il aura toujours un dtype et seuls float et complex peuvent être NaN

Marteau
la source
Je traite de nombreux types de données différents. Alors que la plupart des colonnes ont des types de données int * ou float *, d'autres peuvent être n'importe quel objet, même si jusqu'à présent le seul autre type que j'ai utilisé était une chaîne.
Dun Peal
Les chaînes en python n'ont pas dtype. Vous pourriez avoir à fairetype(val) == 'float'
pvarma
4
type(val) == float and np.isnan(val)- a travaillé pour moi
Danny Cullen
@ user1930402 Je suppose que ce sont des tableaux numpy et non des tableaux Python réguliers. Par exemple: np.array (["hello"]) [0] .dtype fonctionne mais ["hello"] [0] .dtype ne le fait pas
Hammer