Bagaimana cara menghapus Nan dari daftar Python / NumPy

96

Saya memiliki daftar yang menghitung nilai, salah satu nilai yang saya dapatkan adalah 'nan'

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

Saya mencoba untuk menghapusnya, tetapi saya selalu mendapatkan kesalahan

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

Ketika saya mencoba yang ini:

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''
pengguna3001937
sumber
4
Itu terlihat seperti string "nan", bukan nilai NaN yang sebenarnya.
BrenBarn
1
ya, itu adalah sebuah string. [x untuk x di negara-negara jika x! = 'nan']
MarshalSHI
4
if condition == Truetidak perlu, Anda selalu bisa melakukannya if condition.
reem
Tidak ada solusi yang diberikan sejauh ini yang tidak memuaskan. Saya memiliki masalah yang sama. Pada dasarnya, ini tidak berfungsi untuk string. Oleh karena itu dalam kasus Anda np.isnan('USA')akan mengirimkan pesan kesalahan yang sama. Jika saya menemukan solusi, saya akan mengunggahnya.
Yohan Obadia

Jawaban:

131

Pertanyaannya telah berubah, jadi memiliki jawabannya:

String tidak dapat diuji menggunakan math.isnankarena ini mengharapkan argumen float. Dalam countriesdaftar Anda, Anda memiliki pelampung dan string.

Dalam kasus Anda, berikut ini sudah cukup:

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

Jawaban lama

Dalam countriesdaftar Anda , literal 'nan'adalah string bukan float Python nanyang setara dengan:

float('NaN')

Dalam kasus Anda, berikut ini sudah cukup:

cleanedList = [x for x in countries if x != 'nan']
Komunitas
sumber
1
Logikanya, apa yang Anda katakan itu benar. Tapi itu tidak berhasil denganku.
user3001937
Kemudian masalahnya ada di area lain, array yang Anda berikan adalah string yang math.isnansecara alami akan melalui kesalahan.
Iya ! ketika saya mencetak hasilnya, saya mendapatkan ini: [nan, 'USA', 'UK', 'France']
user3001937
1
@ user3001937 Saya telah memperbarui jawaban berdasarkan informasi baru
2
zhangxaochen: ini bukan string, ini pelampung. Perhatikan baik-baik jawaban yang diperbarui; Lego Stormtroopr mengonversi xmenjadi string sehingga Anda dapat membandingkannya. nanselalu mengembalikan false untuk ==, bahkan jika dibandingkan dengan nan, jadi itulah cara termudah untuk membandingkannya.
Gratis Monica Cellio
17

Masalahnya berasal dari fakta bahwa np.isnan()tidak menangani nilai string dengan benar. Misalnya, jika Anda melakukan:

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

Namun versi pandas pd.isnull()berfungsi untuk nilai numerik dan string:

pd.isnull("A")
> False

pd.isnull(3)
> False

pd.isnull(np.nan)
> True

pd.isnull(None)
> True
Yohan Obadia
sumber
15

Menggunakan contoh Anda di mana ...

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

Karena nan tidak sama dengan nan (nan! = Nan) dan negara [0] = nan, Anda harus memperhatikan hal berikut:

countries[0] == countries[0]
False

Namun,

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

Oleh karena itu, berikut ini seharusnya berhasil:

cleanedList = [x for x in countries if x == x]
vlmercado.dll
sumber
1
Ini adalah satu-satunya jawaban yang berfungsi saat Anda memiliki pelampung ('nan') dalam daftar string
kmundnic
13
import numpy as np

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

Ini harus menghapus semua NaN. Tentu saja, saya berasumsi bahwa ini bukan string tetapi NaN ( np.nan) sebenarnya .

Ajay Shah
sumber
1
Ini memberi saya kesalahan: TypeError: ufunc 'isnan' tidak didukung untuk jenis masukan, dan masukan tidak dapat dipaksa dengan aman ke jenis yang didukung sesuai dengan aturan casting '' aman ''
Zak Keirn
1
Mengapa tidak sederhana x[~ np.isnan(x)]:? Tidak ada pemahaman daftar yang diperlukan di numpy. Tentu saja, saya menganggap x adalah array numpy.
bue
Saya berasumsi x tidak akan menjadi array numpy seperti pertanyaan yang disarankan.
Ajay Shah
Ini akan mengharapkan float. Tidak akan bekerja pada daftar dengan string @ZakKeirn
Shirish Bajpai
7

Saya suka menghapus nilai yang hilang dari daftar seperti ini:

list_no_nan = [x for x in list_with_nan if pd.notnull(x)]
Aaron Inggris
sumber
6

jika Anda memeriksa jenis elemen

type(countries[1])

hasilnya akan <class float> jadi kamu bisa menggunakan kode berikut:

[i for i in countries if type(i) is not float]
Beyran 11
sumber
5

gunakan pengindeksan mewah numpy :

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

In [30]: countries[countries!='nan']
Out[30]: 
array(['USA', 'UK', 'France'], 
      dtype='|S6')
zhangxaochen
sumber
2

Cara lain untuk melakukannya termasuk menggunakan filter seperti ini:

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

Dalam contoh Anda 'nan'adalah string jadi alih-alih menggunakan isnan()hanya memeriksa string

seperti ini:

cleanedList = [x for x in countries if x != 'nan']
Serial
sumber
-1

Saya perhatikan bahwa Panda misalnya akan mengembalikan 'nan' untuk nilai kosong. Karena ini bukan string, Anda perlu mengubahnya menjadi satu untuk mencocokkannya. Sebagai contoh:

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)
burung gereja
sumber