Comment puis-je supprimer Nan de la liste Python / NumPy

89

J'ai une liste qui compte des valeurs, l'une des valeurs que j'ai est 'nan'

countries= [nan, 'USA', 'UK', 'France']

J'ai essayé de le supprimer, mais j'obtiens à chaque fois une erreur

cleanedList = [x for x in countries if (math.isnan(x) == True)]
TypeError: a float is required

Quand j'ai essayé celui-ci:

cleanedList = cities[np.logical_not(np.isnan(countries))]
cleanedList = cities[~np.isnan(countries)]

TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
user3001937
la source
4
Cela ressemble à la chaîne "nan", pas à une valeur NaN réelle.
BrenBarn
1
oui, c'est une chaîne. [x pour x dans les pays si x! = 'nan']
MarshalSHI
4
if condition == Trueest inutile, vous pouvez toujours le faire if condition.
reem le
Aucune solution fournie jusqu'à présent n'est satisfaisante. J'ai le même problème. Fondamentalement, cela ne fonctionne pas pour les chaînes. Par conséquent, dans votre cas np.isnan('USA')enverra le même message d'erreur. Si je trouve une solution, je la téléchargerai.
Yohan Obadia le

Réponses:

127

La question a changé, donc la réponse:

Les chaînes ne peuvent pas être testées en utilisant math.isnancar cela attend un argument float. Dans votre countriesliste, vous avez des flotteurs et des chaînes.

Dans votre cas, ce qui suit devrait suffire:

cleanedList = [x for x in countries if str(x) != 'nan']

Ancienne réponse

Dans votre countriesliste, le littéral 'nan'est une chaîne et non le flottant Python nanqui équivaut à:

float('NaN')

Dans votre cas, ce qui suit devrait suffire:

cleanedList = [x for x in countries if x != 'nan']
Communauté
la source
1
Logiquement, ce que vous dites est vrai. Mais ça n'a pas marché avec moi.
user3001937
Ensuite, le problème est dans un autre domaine, le tableau que vous avez donné est des chaînes qui se math.isnanproduiront naturellement par des erreurs.
Oui ! quand j'imprime la sortie, j'ai ceci: [nan, 'USA', 'UK', 'France']
user3001937
1
@ user3001937 J'ai mis à jour la réponse en fonction des nouvelles informations
2
zhangxaochen: ce n'est pas une corde, c'est un flotteur. Regardez attentivement la réponse mise à jour; La conversion de Lego Stormtroopr xen une chaîne pour que vous puissiez la comparer. nanrenvoie toujours false pour ==, même par rapport à nan, c'est donc le moyen le plus simple de le comparer.
Monica Cellio gratuit le
17

Le problème vient du fait que np.isnan()ne gère pas correctement les valeurs de chaîne. Par exemple, si vous faites:

np.isnan("A")
TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

Cependant, la version pandas pd.isnull()fonctionne pour les valeurs numériques et de chaîne:

pd.isnull("A")
> False

pd.isnull(3)
> False

pd.isnull(np.nan)
> True

pd.isnull(None)
> True
Yohan Obadia
la source
14

En utilisant votre exemple où ...

countries= [nan, 'USA', 'UK', 'France']

Étant donné que nan n'est pas égal à nan (nan! = Nan) et pays [0] = nan, vous devez observer les éléments suivants:

countries[0] == countries[0]
False

cependant,

countries[1] == countries[1]
True
countries[2] == countries[2]
True
countries[3] == countries[3]
True

Par conséquent, les éléments suivants devraient fonctionner:

cleanedList = [x for x in countries if x == x]
vlmercado
la source
1
C'est la seule réponse qui fonctionne lorsque vous avez un float ('nan') dans une liste de chaînes
kmundnic
13
import numpy as np

mylist = [3, 4, 5, np.nan]
l = [x for x in mylist if ~np.isnan(x)]

Cela devrait supprimer tout NaN. Bien sûr, je suppose que ce n'est pas une chaîne ici mais du NaN ( np.nan).

Ajay Shah
la source
1
Cela me donne une erreur: TypeError: ufunc 'isnan' n'est pas pris en charge pour les types d'entrée, et les entrées ne peuvent pas être forcées en toute sécurité à des types pris en charge selon la règle de diffusion `` safe ''
Zak Keirn
1
Pourquoi pas simplement x[~ np.isnan(x)]:? Aucune compréhension de liste nécessaire dans numpy. Bien sûr, je suppose que x est un tableau numpy.
prévu
J'ai supposé que x ne serait pas un tableau numpy comme la question le suggérait.
Ajay Shah
Il s'attendra à flotter. Ne fonctionnera pas sur les listes avec des chaînes @ZakKeirn
Shirish Bajpai
5

utilisez l' indexation fantaisie numpy :

In [29]: countries=np.asarray(countries)

In [30]: countries[countries!='nan']
Out[30]: 
array(['USA', 'UK', 'France'], 
      dtype='|S6')
Zhangxaochen
la source
5

si vous vérifiez le type d'élément

type(countries[1])

le résultat sera <class float> que vous pouvez utiliser le code suivant:

[i for i in countries if type(i) is not float]
Beyran11
la source
4

J'aime supprimer les valeurs manquantes d'une liste comme celle-ci:

list_no_nan = [x for x in list_with_nan if pd.notnull(x)]
Aaron Angleterre
la source
1

Dans votre exemple, il 'nan'y a une chaîne, donc au lieu d'utiliser, isnan()vérifiez simplement la chaîne

comme ça:

cleanedList = [x for x in countries if x != 'nan']
En série
la source
0

Une autre façon de le faire consisterait à utiliser un filtre comme celui-ci:

countries = list(filter(lambda x: str(x) != 'nan', countries))
Sorin Dragan
la source
-1

J'ai remarqué que Pandas, par exemple, renverra «nan» pour les valeurs vides. Comme ce n'est pas une chaîne, vous devez la convertir en une chaîne pour la faire correspondre. Par exemple:

ulist = df.column1.unique() #create a list from a column with Pandas which 
for loc in ulist:
    loc = str(loc)   #here 'nan' is converted to a string to compare with if
    if loc != 'nan':
        print(loc)
moineau
la source