web-dev-qa-db-fra.com

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

Mes tableaux numpy utilisent np.nan pour désigner les valeurs manquantes. En parcourant l'ensemble de données, j'ai besoin de détecter ces valeurs manquantes et de les gérer de manière particulière.

Naïvement j'ai utilisé numpy.isnan(val), qui fonctionne bien à moins que val ne fasse pas partie du sous-ensemble de types pris en charge par numpy.isnan(). Par exemple, des données manquantes peuvent apparaître dans des champs de chaîne, auquel cas je reçois:

>>> 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 intercepte l'exception et renvoie False, existe-t-il un moyen de gérer cela de manière élégante et efficace?

86
Dun Peal

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

NaN dans les tableaux numériques, Aucun/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.nan pour représenter les valeurs manquantes est une chose que pandas a introduite. C'est pourquoi pandas dispose des outils pour le gérer.

Les dates aussi (si vous utilisez pd.NaT vous n'aurez pas besoin de spécifier le type)

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
143
Marius

Votre type est-il vraiment arbitraire? Si vous savez que ça va juste être un float int ou une chaîne que vous pourriez faire

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

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

16
Hammer