¿Cómo puedo eliminar a Nan de la lista Python / NumPy?


89

Tengo una lista que cuenta valores, uno de los valores que obtuve es 'nan'

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

Traté de eliminarlo, pero cada vez aparece un error

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

Cuando probé este:

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''

4
Parece la cadena "nan", no un valor real de NaN.
BrenBarn

1
sí, es una cuerda. [x para x en países si x! = 'nan']
MarshalSHI

4
if condition == Truees innecesario, siempre puedes hacerlo if condition.
reem

Ninguna solución proporcionada hasta ahora no es satisfactoria. Tengo el mismo problema. Básicamente, no funciona con cadenas. Por tanto en su caso np.isnan('USA')le enviará el mismo mensaje de error. Si encuentro alguna solución, la subiré.
Yohan Obadia

Respuestas:


127

La pregunta ha cambiado, por lo que tiene la respuesta:

Las cadenas no se pueden probar usando math.isnanya que esto espera un argumento flotante. En su countrieslista, tiene flotadores y cuerdas.

En su caso, lo siguiente debería ser suficiente:

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

Respuesta antigua

En su countrieslista, el literal 'nan'es una cadena, no el flotante de Python, nanque es equivalente a:

float('NaN')

En su caso, lo siguiente debería ser suficiente:

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

1
Lógicamente, lo que dices es cierto. Pero no funcionó conmigo.
user3001937

Entonces el problema está en otra área, la matriz que proporcionó son cadenas que math.isnanse corregirán naturalmente con los errores.

Si ! cuando imprimo la salida, obtengo esto: [nan, 'USA', 'UK', 'France']
user3001937

1
@ user3001937 He actualizado la respuesta según la nueva información

2
zhangxaochen: no es una cuerda, es un flotador. Mire cuidadosamente la respuesta actualizada; Lego Stormtroopr se está convirtiendo xen una cadena para que puedas compararlo. nansiempre devuelve falso para ==, incluso cuando se compara con nan, por lo que esa es la forma más fácil de compararlo.
Monica Cellio gratis

17

El problema proviene del hecho de que np.isnan()no maneja correctamente los valores de cadena. Por ejemplo, si lo hace:

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''

Sin embargo, la versión de pandas pd.isnull()funciona para valores numéricos y de cadena:

pd.isnull("A")
> False

pd.isnull(3)
> False

pd.isnull(np.nan)
> True

pd.isnull(None)
> True

14

Usando su ejemplo donde ...

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

Dado que nan no es igual a nan (nan! = Nan) y los países [0] = nan, debes observar lo siguiente:

countries[0] == countries[0]
False

Sin embargo,

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

Por lo tanto, lo siguiente debería funcionar:

cleanedList = [x for x in countries if x == x]

1
Esta es la única respuesta que funciona cuando tiene un flotador ('nan') en una lista de cadenas
kmundnic

12
import numpy as np

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

Esto debería eliminar todo el NaN. Por supuesto, supongo que no es una cadena aquí, sino un NaN ( np.nan) real .


1
Esto me da un error: TypeError: ufunc 'isnan' no es compatible con los tipos de entrada, y las entradas no se pudieron forzar de forma segura a ningún tipo compatible de acuerdo con la regla de conversión '' segura ''
Zak Keirn

1
¿Por qué no simplemente x[~ np.isnan(x)]:? No se necesita comprensión de listas en numpy. Por supuesto, supongo que x es una matriz numerosa.
bue

Supuse que x no va a ser una matriz numerosa como sugiere la pregunta.
Ajay Shah

Esperará flotación. No funcionará en listas con cadenas @ZakKeirn
Shirish Bajpai


5

si comprueba el tipo de elemento

type(countries[1])

el resultado será <class float> que puedas usar el siguiente código:

[i for i in countries if type(i) is not float]

4

Me gusta eliminar los valores faltantes de una lista como esta:

list_no_nan = [x for x in list_with_nan if pd.notnull(x)]

1

En su ejemplo, 'nan'es una cadena, así que en lugar de usar isnan()solo verifique la cadena

Me gusta esto:

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

0

Otra forma de hacerlo incluiría usar un filtro como este:

countries = list(filter(lambda x: str(x) != 'nan', countries))

-1

Noté que Pandas, por ejemplo, devolverá 'nan' para valores en blanco. Como no es una cadena, debe convertirla en una para que coincida. Por ejemplo:

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)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.