Tôi muốn tìm ra cách loại bỏ các giá trị nan khỏi mảng của tôi. Mảng của tôi trông giống như thế này:
x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration
Làm thế nào tôi có thể loại bỏ các nan
giá trị từ x
?
Tôi muốn tìm ra cách loại bỏ các giá trị nan khỏi mảng của tôi. Mảng của tôi trông giống như thế này:
x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration
Làm thế nào tôi có thể loại bỏ các nan
giá trị từ x
?
Câu trả lời:
Nếu bạn đang sử dụng numpy cho mảng của mình, bạn cũng có thể sử dụng
x = x[numpy.logical_not(numpy.isnan(x))]
Tương đương
x = x[~numpy.isnan(x)]
[Cảm ơn chbrown cho tốc ký thêm]
Giải trình
Hàm bên trong, numpy.isnan
trả về một mảng boolean / logic có giá trị True
ở mọi nơi x
không phải là số. Như chúng ta muốn ngược lại, chúng ta sử dụng toán tử không logic, ~
để lấy một mảng có True
s ở mọi nơi x
là số hợp lệ.
Cuối cùng, chúng tôi sử dụng mảng logic này để lập chỉ mục vào mảng ban đầu x
, để chỉ truy xuất các giá trị không phải NaN.
x = x[numpy.isfinite(x)]
x = x[~numpy.isnan(x)]
, tương đương với câu trả lời ban đầu của mutzmatron, nhưng ngắn hơn. Trong trường hợp bạn muốn giữ sự vô tận của mình, hãy biết rằng numpy.isfinite(numpy.inf) == False
, tất nhiên, nhưng ~numpy.isnan(numpy.inf) == True
.
np.where(np.isfinite(x), x, 0)
x
không phải là một mảng numpy. Nếu bạn muốn sử dụng chỉ mục hợp lý, nó phải là một mảng - ví dụx = np.array(x)
filter(lambda v: v==v, x)
hoạt động cả cho danh sách và mảng numpy vì v! = v chỉ dành cho NaN
x
được chỉ định một lần trái ngược với các giải pháp của loại x[~numpy.isnan(x)]
. Điều này thuận tiện khi x
được xác định bởi một biểu thức dài và bạn không muốn làm lộn xộn mã bằng cách tạo một biến tạm thời để lưu trữ kết quả của biểu thức dài này.
Thử cái này:
import math
print [value for value in x if not math.isnan(value)]
Để biết thêm, đọc trên Danh sách toàn diện .
print ([value for value in x if not math.isnan(value)])
np
gói: Vì vậy, trả về danh sách của bạn mà không cần nans:[value for value in x if not np.isnan(value)]
Đối với tôi, câu trả lời của @jmetz không hiệu quả, tuy nhiên sử dụng gấu trúc isnull () đã làm.
x = x[~pd.isnull(x)]
Làm như trên:
x = x[~numpy.isnan(x)]
hoặc là
x = x[numpy.logical_not(numpy.isnan(x))]
Tôi thấy rằng việc đặt lại cùng một biến (x) không loại bỏ các giá trị nan thực tế và phải sử dụng một biến khác. Đặt nó vào một biến khác đã loại bỏ các nans. ví dụ
y = x[~numpy.isnan(x)]
x
đè lên giá trị mới (tức là không có NaNs ...) . Bạn có thể cung cấp thêm thông tin về lý do tại sao điều này có thể xảy ra?
Như được hiển thị bởi những người khác
x[~numpy.isnan(x)]
làm. Nhưng nó sẽ đưa ra một lỗi nếu dtype numpy không phải là kiểu dữ liệu nguyên gốc, ví dụ nếu nó là đối tượng. Trong trường hợp đó bạn có thể sử dụng gấu trúc.
x[~pandas.isna(x)] or x[~pandas.isnull(x)]
Các câu trả lời được chấp nhận thay đổi hình dạng cho mảng 2ngày. Tôi trình bày một giải pháp ở đây, sử dụng chức năng Pandas dropna () . Nó hoạt động cho mảng 1D và 2D. Trong trường hợp 2D, bạn có thể chọn thời tiết để thả hàng hoặc cột chứa np.nan
.
import pandas as pd
import numpy as np
def dropna(arr, *args, **kwarg):
assert isinstance(arr, np.ndarray)
dropped=pd.DataFrame(arr).dropna(*args, **kwarg).values
if arr.ndim==1:
dropped=dropped.flatten()
return dropped
x = np.array([1400, 1500, 1600, np.nan, np.nan, np.nan ,1700])
y = np.array([[1400, 1500, 1600], [np.nan, 0, np.nan] ,[1700,1800,np.nan]] )
print('='*20+' 1D Case: ' +'='*20+'\nInput:\n',x,sep='')
print('\ndropna:\n',dropna(x),sep='')
print('\n\n'+'='*20+' 2D Case: ' +'='*20+'\nInput:\n',y,sep='')
print('\ndropna (rows):\n',dropna(y),sep='')
print('\ndropna (columns):\n',dropna(y,axis=1),sep='')
print('\n\n'+'='*20+' x[np.logical_not(np.isnan(x))] for 2D: ' +'='*20+'\nInput:\n',y,sep='')
print('\ndropna:\n',x[np.logical_not(np.isnan(x))],sep='')
Kết quả:
==================== 1D Case: ====================
Input:
[1400. 1500. 1600. nan nan nan 1700.]
dropna:
[1400. 1500. 1600. 1700.]
==================== 2D Case: ====================
Input:
[[1400. 1500. 1600.]
[ nan 0. nan]
[1700. 1800. nan]]
dropna (rows):
[[1400. 1500. 1600.]]
dropna (columns):
[[1500.]
[ 0.]
[1800.]]
==================== x[np.logical_not(np.isnan(x))] for 2D: ====================
Input:
[[1400. 1500. 1600.]
[ nan 0. nan]
[1700. 1800. nan]]
dropna:
[1400. 1500. 1600. 1700.]
Một cách đơn giản nhất là:
numpy.nan_to_num(x)
Tài liệu: https://docs.scipy.org/doc/numpy/reference/generated/numpy.nan_to_num.html
NaN
s với số lượng lớn, trong khi OP yêu cầu loại bỏ hoàn toàn các yếu tố.
Đây là cách tiếp cận của tôi để lọc ndarray "X" cho NaN và infs,
Tôi tạo một bản đồ các hàng mà không có bất kỳ NaN
và bất kỳ inf
như sau:
idx = np.where((np.isnan(X)==False) & (np.isinf(X)==False))
idx là một tuple. Cột thứ hai ( idx[1]
) chứa các chỉ mục của mảng, trong đó không có NaN cũng như inf được tìm thấy trên hàng.
Sau đó:
filtered_X = X[idx[1]]
filtered_X
chứa X mà không NaN
hay inf
.
Câu trả lời của @ jmetz có lẽ là câu hỏi mà nhiều người cần nhất; tuy nhiên, nó mang lại một mảng một chiều, ví dụ như làm cho nó không thể sử dụng để loại bỏ toàn bộ hàng hoặc cột trong ma trận.
Để làm như vậy, người ta nên giảm mảng logic xuống một chiều, sau đó lập chỉ mục cho mảng mục tiêu. Chẳng hạn, những điều sau đây sẽ xóa các hàng có ít nhất một giá trị NaN:
x = x[~numpy.isnan(x).any(axis=1)]
Xem thêm chi tiết tại đây .