Saya ingin mencari cara untuk menghapus nilai-nilai nan dari array saya. Array saya terlihat seperti ini:
x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration
Bagaimana cara menghapus nan
nilai dari x
?
Saya ingin mencari cara untuk menghapus nilai-nilai nan dari array saya. Array saya terlihat seperti ini:
x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration
Bagaimana cara menghapus nan
nilai dari x
?
Jawaban:
Jika Anda menggunakan numpy untuk array Anda, Anda juga dapat menggunakan
x = x[numpy.logical_not(numpy.isnan(x))]
Setara
x = x[~numpy.isnan(x)]
[Terima kasih sudah menambahkan singkatan yang ditambahkan]
Penjelasan
Fungsi dalam, numpy.isnan
mengembalikan array boolean / logis yang memiliki nilai di True
mana-mana yang x
bukan-angka. Seperti yang kita inginkan sebaliknya, kita menggunakan operator logical-not, ~
untuk mendapatkan array dengan True
s di mana-mana yang x
merupakan angka yang valid.
Terakhir kami menggunakan array logis ini untuk mengindeks ke dalam array asli x
, untuk mengambil hanya nilai-nilai non-NaN.
x = x[numpy.isfinite(x)]
x = x[~numpy.isnan(x)]
, yang setara dengan jawaban asli mutzmatron, tetapi lebih pendek. Jika Anda ingin menjaga ketidakterbatasan Anda, ketahuilah numpy.isfinite(numpy.inf) == False
, tentu saja, tetapi ~numpy.isnan(numpy.inf) == True
.
np.where(np.isfinite(x), x, 0)
x
bukan array yang numpy. Jika Anda ingin menggunakan pengindeksan logis, itu harus berupa array - misalnyax = np.array(x)
filter(lambda v: v==v, x)
berfungsi baik untuk daftar dan array numpy karena v! = v hanya untuk NaN
x
ditentukan sekali sebagai lawan dari solusi jenis x[~numpy.isnan(x)]
. Ini nyaman ketika x
didefinisikan oleh ekspresi panjang dan Anda tidak ingin mengacaukan kode dengan membuat variabel sementara untuk menyimpan hasil dari ekspresi panjang ini.
Coba ini:
import math
print [value for value in x if not math.isnan(value)]
Untuk lebih lanjut, baca tentang Pemahaman Daftar .
print ([value for value in x if not math.isnan(value)])
np
paket: Jadi kembalikan daftar Anda tanpa [value for value in x if not np.isnan(value)]
Bagi saya jawaban oleh @jmetz tidak bekerja, namun menggunakan panda isnull () berhasil.
x = x[~pd.isnull(x)]
Melakukan hal di atas:
x = x[~numpy.isnan(x)]
atau
x = x[numpy.logical_not(numpy.isnan(x))]
Saya menemukan bahwa pengaturan ulang ke variabel yang sama (x) tidak menghapus nilai nan aktual dan harus menggunakan variabel yang berbeda. Mengaturnya ke variabel yang berbeda menghapus nans. misalnya
y = x[~numpy.isnan(x)]
x
dengan nilai baru (yaitu tanpa NaNs ...) . Bisakah Anda memberikan info lebih lanjut mengapa ini bisa terjadi?
Seperti yang ditunjukkan oleh orang lain
x[~numpy.isnan(x)]
bekerja. Tapi itu akan menimbulkan kesalahan jika tipe numpy bukan tipe data asli, misalnya jika objek. Dalam hal ini Anda dapat menggunakan panda.
x[~pandas.isna(x)] or x[~pandas.isnull(x)]
The jawaban yang diterima berubah bentuk untuk array 2d. Saya menyajikan solusi di sini, menggunakan fungsionalitas dropna () Pandas . Ini bekerja untuk array 1D dan 2D. Dalam kasus 2D Anda dapat memilih cuaca untuk menjatuhkan baris atau kolom yang berisi 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='')
Hasil:
==================== 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.]
Cara paling sederhana adalah:
numpy.nan_to_num(x)
Dokumentasi: https://docs.scipy.org/doc/numpy/reference/generated/numpy.nan_to_num.html
NaN
sejumlah besar, sedangkan OP diminta untuk sepenuhnya menghapus elemen.
Ini adalah pendekatan saya untuk menyaring ndarray "X" untuk NaNs dan infs,
Saya membuat peta baris tanpa NaN
dan apa pun inf
sebagai berikut:
idx = np.where((np.isnan(X)==False) & (np.isinf(X)==False))
idx adalah tuple. Ini kolom kedua ( idx[1]
) berisi indeks array, di mana tidak ada NaN atau inf di mana ditemukan di sepanjang baris.
Kemudian:
filtered_X = X[idx[1]]
filtered_X
berisi X tanpa NaN
atau inf
.
@ jawaban jmetz mungkin yang paling dibutuhkan orang; namun ia menghasilkan array satu dimensi, misalnya membuatnya tidak dapat digunakan untuk menghapus seluruh baris atau kolom dalam matriks.
Untuk melakukannya, kita harus mengurangi larik logis menjadi satu dimensi, lalu mengindeks larik target. Misalnya, berikut ini akan menghapus baris yang memiliki setidaknya satu nilai NaN:
x = x[~numpy.isnan(x).any(axis=1)]
Lihat lebih detail di sini .