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

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

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

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]

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 .


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)]

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]

5

gunakan pengindeksan mewah numpy :

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

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

2

Cara lain untuk melakukannya termasuk menggunakan filter seperti ini:

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

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

-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)
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.