Làm cách nào để xóa Nan khỏi danh sách Python / NumPy


89

Tôi có một danh sách đếm các giá trị, một trong những giá trị tôi nhận được là 'nan'

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

Tôi đã cố gắng xóa nó, nhưng tôi luôn gặp lỗi

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

Khi tôi thử cái này:

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
Điều đó trông giống như chuỗi "nan", không phải là giá trị NaN thực tế.
BrenBarn

1
vâng, nó là một chuỗi. [x cho x ở các quốc gia nếu x! = 'nan']
MarshalSHI

4
if condition == Truelà không cần thiết, bạn luôn có thể làm if condition.
reem

Không có giải pháp nào được cung cấp cho đến nay là không thỏa mãn. Tôi có cùng một vấn đề. Về cơ bản, nó không hoạt động đối với chuỗi. Do đó trong trường hợp của bạn np.isnan('USA')sẽ gửi thông báo lỗi tương tự. Nếu tôi tìm thấy giải pháp nào đó, tôi sẽ tải nó lên.
Yohan Obadia

Câu trả lời:


127

Câu hỏi đã thay đổi, vì vậy để có câu trả lời:

Không thể kiểm tra các chuỗi bằng cách sử dụng math.isnanvì điều này mong đợi một đối số float. Trong countriesdanh sách của bạn , bạn có phao và chuỗi.

Trong trường hợp của bạn, những điều sau đây là đủ:

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

Câu trả lời cũ

Trong countriesdanh sách của bạn , nghĩa đen 'nan'là một chuỗi không phải là float Python nantương đương với:

float('NaN')

Trong trường hợp của bạn, những điều sau đây là đủ:

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

1
Về mặt logic, những gì bạn nói là đúng. Nhưng nó không thành công với tôi.
user3001937

Sau đó, vấn đề là ở một khu vực khác, mảng bạn đã cung cấp là các chuỗi math.isnansẽ tự nhiên có lỗi.

Đúng ! khi tôi in ra, tôi nhận điều này: [nan, 'Hoa Kỳ', 'Anh', 'Pháp']
user3001937

1
@ user3001937 Tôi đã cập nhật câu trả lời dựa trên các thông tin mới

2
zhangxaochen: nó không phải là một chuỗi, nó là một cái phao. Xem kỹ câu trả lời đã cập nhật; Lego Stormtroopr đang chuyển đổi xthành một chuỗi để bạn có thể so sánh. nanluôn trả về false cho ==, ngay cả khi so sánh với nan, vì vậy đó là cách dễ nhất để so sánh nó.
Miễn phí Monica Cellio

17

Vấn đề xuất phát từ thực tế là np.isnan()không xử lý các giá trị chuỗi một cách chính xác. Ví dụ, nếu bạn làm:

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

Tuy nhiên, phiên bản gấu trúc pd.isnull()hoạt động cho các giá trị số và chuỗi:

pd.isnull("A")
> False

pd.isnull(3)
> False

pd.isnull(np.nan)
> True

pd.isnull(None)
> True

14

Sử dụng ví dụ của bạn trong đó ...

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

Vì nan không bằng nan (nan! = Nan) và nước [0] = nan, bạn nên quan sát những điều sau:

countries[0] == countries[0]
False

Tuy nhiên,

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

Do đó, những điều sau đây sẽ hoạt động:

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

1
Đây là chỉ trả lời rằng công trình khi bạn có một phao ( 'nan') trong một danh sách các chuỗi
kmundnic

13
import numpy as np

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

Điều này sẽ loại bỏ tất cả NaN. Tất nhiên, tôi giả định rằng nó không phải là một chuỗi ở đây mà là NaN thực tế ( np.nan).


1
Điều này cho phép tôi lỗi: Lỗi Loại: ufunc 'isNaN' không được hỗ trợ cho các loại đầu vào, và đầu vào không thể ép buộc một cách an toàn đối với bất kỳ loại hỗ trợ theo nguyên tắc đúc '' an toàn ''
Zak Keirn

1
Tại sao không đơn giản là x[~ np.isnan(x)]:? Không cần hiểu danh sách trong numpy. Tất nhiên, tôi giả sử x là một mảng numpy.
bue

Tôi đã giả định x sẽ không phải là một mảng phức tạp như câu hỏi đã đề xuất.
Ajay Shah

Nó sẽ nổi. Sẽ không hoạt động trên danh sách có chuỗi @ZakKeirn
Shirish Bajpai


5

nếu bạn kiểm tra loại phần tử

type(countries[1])

kết quả sẽ là <class float> vì vậy bạn có thể sử dụng mã sau:

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

5

Tôi muốn xóa các giá trị bị thiếu khỏi danh sách như sau:

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

1

Trong ví dụ của bạn 'nan'là một chuỗi, vì vậy thay vì sử dụng isnan()chỉ cần kiểm tra chuỗi

như thế này:

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

0

Một cách khác để làm điều đó sẽ bao gồm sử dụng bộ lọc như sau:

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

-1

Tôi nhận thấy rằng ví dụ như Pandas sẽ trả về 'nan' cho các giá trị trống. Vì nó không phải là một chuỗi nên bạn cần chuyển đổi nó thành một chuỗi để khớp với nó. Ví dụ:

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.