145 votes

Vérifier efficacement si un objet arbitraire est NaN en Python / numpy / pandas ?

Mes tableaux numpy utilisent np.nan pour désigner les valeurs manquantes. Lorsque j'itère sur l'ensemble des données, je dois détecter ces valeurs manquantes et les traiter de manière spéciale.

Naïvement, j'ai utilisé numpy.isnan(val) ce qui fonctionne bien, sauf si val ne fait pas partie du sous-ensemble de types pris en charge par le système numpy.isnan() . Par exemple, les données manquantes peuvent se trouver dans des champs de type chaîne de caractères, 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

À part écrire un wrapper coûteux qui attrape l'exception et retourne False existe-t-il un moyen de traiter cette question de manière élégante et efficace ?

227voto

Marius Points 8425

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

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

Un 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.nan pour représenter les valeurs manquantes est quelque chose qui pandas introduit, c'est pourquoi pandas a les outils pour y faire face.

Les dates aussi (si vous utilisez pd.NaT vous 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

25voto

Hammer Points 4435

Votre type est vraiment arbitraire ? Si vous savez que ce sera juste un int, un float ou une chaîne de caractères, vous pouvez simplement faire

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

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

11voto

Shahin Shirazi Points 43

J'ai trouvé cette brillante solution ici, elle utilise la simple logique NAN!=NAN. https://www.codespeedy.com/check-if-a-given-string-is-nan-in-python/

En utilisant l'exemple ci-dessus, vous pouvez simplement faire ce qui suit. Cela devrait fonctionner sur différents types d'objets car cela utilise simplement le fait que NAN n'est pas égal à NAN.

 import numpy as np
 s = pd.Series(['apple', np.nan, 'banana'])
 s.apply(lambda x: x!=x)
 out[252]
 0    False
 1     True
 2    False
 dtype: bool

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X