Quelle est la différence entre NaN et None?

94

Je lis deux colonnes d'un fichier csv en utilisant des pandas readcsv(), puis j'attribue les valeurs à un dictionnaire. Les colonnes contiennent des chaînes de chiffres et de lettres. Parfois, il y a des cas où une cellule est vide. À mon avis, la valeur lue dans cette entrée de dictionnaire devrait être, Nonemais nanest affectée à la place. NoneEst sûrement plus descriptif d'une cellule vide car elle a une valeur nulle, alors nanque dit simplement que la valeur lue n'est pas un nombre.

Ma compréhension est-elle correcte, quelle est la différence entre Noneet nan? Pourquoi est nanattribué au lieu de None?

De plus, ma vérification du dictionnaire pour toutes les cellules vides utilise numpy.isnan():

for k, v in my_dict.iteritems():
    if np.isnan(v):

Mais cela me donne une erreur disant que je ne peux pas utiliser cette vérification v. Je suppose que c'est parce qu'une variable entière ou flottante, et non une chaîne, est destinée à être utilisée. Si cela est vrai, comment puis-je vrechercher une "cellule vide" / un nancas?

utilisateur1083734
la source
Le texte qwertyn'est pas un nombre.
Robert Harvey
1
@RobertHarvey Je sais, ce Noneserait sûrement une meilleure description de la valeur d'une cellule vide.
user1083734

Réponses:

107

NaN est utilisé comme espace réservé pour les données manquantes de manière cohérente dans les pandas , la cohérence est bonne. Je lis / traduis habituellement NaN comme "manquant" . Consultez également la section «Utilisation des données manquantes» dans la documentation.

Wes écrit dans la documentation `` le choix de la représentation NA '' :

Après des années de production, l'utilisation de [NaN] s'est avérée, du moins à mon avis, la meilleure décision étant donné l'état des choses dans NumPy et Python en général. La valeur spéciale NaN (Not-A-Number) est utilisée partout comme valeur NA, et il existe des fonctions API isnullet notnullqui peuvent être utilisées dans les dtypes pour détecter les valeurs NA.
...
Ainsi, j'ai choisi l'approche pythonique «la praticité bat la pureté» et j'ai échangé la capacité NA entière pour une approche beaucoup plus simple consistant à utiliser une valeur spéciale dans les tableaux flottants et objets pour désigner NA, et en promouvant les tableaux entiers flottants lorsque les NA doivent être introduit.

Remarque: le "gotcha" que les séries entières contenant des données manquantes sont converties en flottants .

À mon avis, la principale raison d'utiliser NaN (sur None) est qu'il peut être stocké avec le type float64 de numpy, plutôt qu'avec le type d'objet moins efficace, voir les promotions de type NA .

#  without forcing dtype it changes None to NaN!
s_bad = pd.Series([1, None], dtype=object)
s_good = pd.Series([1, np.nan])

In [13]: s_bad.dtype
Out[13]: dtype('O')

In [14]: s_good.dtype
Out[14]: dtype('float64')

Jeff commente (ci-dessous) à ce sujet:

np.nanpermet des opérations vectorisées; c'est une valeur flottante, tandis que None, par définition, force le type d'objet, ce qui désactive fondamentalement toute efficacité dans numpy.

Alors répétez 3 fois vite: objet == mauvais, float == bon

Cela dit, de nombreuses opérations peuvent toujours fonctionner aussi bien avec None qu'avec NaN (mais peut-être ne sont pas prises en charge, c'est-à-dire qu'elles peuvent parfois donner des résultats surprenants ):

In [15]: s_bad.sum()
Out[15]: 1

In [16]: s_good.sum()
Out[16]: 1.0

Pour répondre à la deuxième question:
Vous devez utiliser pd.isnullet pd.notnullpour tester les données manquantes (NaN).

Andy Hayden
la source
19
ajouter simplement 2c ici .... np.nanpermet des opérations vectorisées; c'est une valeur flottante, alors que Nonepar définition force le objecttype, et désactive fondamentalement toute efficacité dans numpy, alors répétez 3 fois vite:object==bad, float==good
Jeff
1
Est-ce <NA>aussi un np.nan?
Gathide
18

NaNpeut être utilisé comme valeur numérique sur des opérations mathématiques, alors que Nonene peut pas (ou du moins ne devrait pas).

NaNest une valeur numérique, telle que définie dans la norme à virgule flottante IEEE 754 . Noneest un type Python interne ( NoneType) et ressemblerait plus à «inexistant» ou «vide» qu'à «numériquement invalide» dans ce contexte.

Le principal "symptôme" de cela est que, si vous effectuez, par exemple, une moyenne ou une somme sur un tableau contenant NaN, même un seul, vous obtenez NaN en conséquence ...

En revanche, vous ne pouvez pas effectuer d'opérations mathématiques en utilisant Nonecomme opérande.

Ainsi, selon le cas, vous pouvez utiliser Nonecomme moyen de dire à votre algorithme de ne pas prendre en compte des valeurs invalides ou inexistantes dans les calculs. Cela signifierait que l'algorithme devrait tester chaque valeur pour voir si c'est le cas None.

Numpy a certaines fonctions pour éviter que les valeurs NaN ne contaminent vos résultats, comme nansumet nan_to_numpar exemple.

heltonbiker
la source
Je suis d'accord avec vous sur le fait que None devrait être utilisé pour les entrées inexistantes, alors pourquoi df=pd.readcsv('file.csv')me donne-t-il des NaNvaleurs pour les cellules vides et non None? Autant que je sache, les pd.DataFrames ne sont pas exclusifs aux nombres.
user1083734
Eh bien, c'est probablement un choix de conception. Je suppose que DataFrames et Series ont un dtype, donc les valeurs invalides de dtype=floatdoivent être représentées par des valeurs numériques, ce qui NaNest et Nonen'est pas ( Noneest de NoneType).
heltonbiker
De plus, de nombreuses méthodes Pandas ont un naargument, qui vous permet de décider quelle valeur vous allez utiliser pour remplacer les valeurs non disponibles
heltonbiker
OK merci. Je ne lis donc pas réellement des nombres dans mon DataFrame, mais des chaînes de chiffres et de lettres. Quel type de contrôle dois-je utiliser pour détecter les cellules vides? Un chèque comme; si dtype == float: ??
user1083734
Peut-être que publier un échantillon de vos données CSV serait utile. Je peux imaginer que, s'il y a des chaînes, alors dtype serait une chaîne pour toute la colonne (Series). Mais peut-être que si toutes les lignes n'ont pas le même nombre de colonnes, vous vous retrouvez avec des données indisponibles. Je pense que vous devrez vérifier cela.
heltonbiker
3

La fonction isnan()vérifie si quelque chose est "Not A Number" et retournera si oui ou non une variable est un nombre, par exemple isnan(2)retournerait false

Le conditionnel myVar is not Nonerenvoie si la variable est définie ou non

Votre tableau numpy utilise isnan()parce qu'il est destiné à être un tableau de nombres et qu'il initialise tous les éléments du tableau à NaNces éléments sont considérés comme «vides»

Stephan
la source
1
Je pense que j'y isnan(2)retournerais False, car 2 n'est pas un NaN.
heltonbiker
De plus, numpy.emptyn'initialise pas les valeurs du tableau sur NaN. Il n'initialise tout simplement pas du tout les valeurs.
heltonbiker
5
Le bon contrôle de None-ness est myVar is not None, non myVar != None.
Jaime
3
Notez que ce np.isnan()n'est pas implémenté pour les variables chaîne, donc si vous lui passez une chaîne, cela plantera. Mieux vaut utiliser pd.isnullqui fonctionne avec des chaînes.
Michael
-1

Voici les différences:

  • nan appartient à la classe float
  • None appartient à la classe NoneType

J'ai trouvé l'article ci-dessous très utile: https://medium.com/analytics-vidhya/dealing-with-missing-values-nan-and-none-in-python-6fc9b8fb4f31

eswara amirthan s
la source
Bien que ce lien puisse répondre à la question, il est préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien pour référence. Les réponses aux liens uniquement peuvent devenir invalides si la page liée change. - De l'avis
A. Kootstra
@ A.Kootstra je comprends
eswara amirthan s
-3

NaNstants pour PAS un nombre .
Nonepourrait représenter tout .

diegoaguilar
la source