Agar lebih jelas, dengan "menghapus NaNs" yang Anda maksud hanya memfilter subset dari nilai-nilai yang bukan nol . Bukan "mengisi NaN dengan beberapa nilai (nol, konstan, rata-rata, median, dll.)"
smci
Jawaban:
362
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.isnanmengembalikan array boolean / logis yang memiliki nilai di Truemana-mana yang xbukan-angka. Seperti yang kita inginkan sebaliknya, kita menggunakan operator logical-not, ~untuk mendapatkan array dengan Trues di mana-mana yang xmerupakan angka yang valid.
Terakhir kami menggunakan array logis ini untuk mengindeks ke dalam array asli x, untuk mengambil hanya nilai-nilai non-NaN.
Atau 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.
chbrown
8
Bagi orang yang ingin menyelesaikan ini dengan ndarray dan mempertahankan dimensi, gunakan numpy di mana :np.where(np.isfinite(x), x, 0)
BoltzmannBrain
1
TypeError: hanya array skalar integer yang dapat dikonversi ke indeks skalar
towry
1
@towry: ini terjadi karena input Anda, xbukan array yang numpy. Jika Anda ingin menggunakan pengindeksan logis, itu harus berupa array - misalnyax = np.array(x)
jmetz
50
filter(lambda v: v==v, x)
berfungsi baik untuk daftar dan array numpy karena v! = v hanya untuk NaN
Retasan tetapi yang sangat berguna dalam kasus di mana Anda memfilter nans dari array objek dengan tipe campuran, seperti string dan nans.
Austin Richardson
Solusi yang sangat bersih.
Moondra
2
Ini mungkin tampak pintar, tetapi jika mengaburkan logika dan objek lain secara teoritis (seperti kelas khusus) juga dapat memiliki properti ini
Chris_Rands
Juga berguna karena hanya perlu xditentukan sekali sebagai lawan dari solusi jenis x[~numpy.isnan(x)]. Ini nyaman ketika xdidefinisikan oleh ekspresi panjang dan Anda tidak ingin mengacaukan kode dengan membuat variabel sementara untuk menyimpan hasil dari ekspresi panjang ini.
Christian O'Reilly
34
Coba ini:
import math
print[value for value in x ifnot math.isnan(value)]
Jika Anda menggunakan numpy baik jawaban saya dan bahwa dengan @ lazy1 hampir urutan besarnya lebih cepat daripada pemahaman daftar - solusi lazy1 sedikit lebih cepat (meskipun secara teknis juga tidak akan mengembalikan nilai tak terhingga).
jmetz
Jangan lupa tanda kurung :)print ([value for value in x if not math.isnan(value)])
hypers
Jika Anda menggunakan numpy seperti jawaban teratas maka Anda dapat menggunakan jawaban pemahaman daftar ini dengan nppaket: Jadi kembalikan daftar Anda tanpa [value for value in x if not np.isnan(value)]
nans
23
Bagi saya jawaban oleh @jmetz tidak bekerja, namun menggunakan panda isnull () berhasil.
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
Ini aneh; menurut dokumen , pengindeksan boolean array (yang ini), berada di bawah pengindeksan lanjutan yang tampaknya "selalu mengembalikan salinan data", jadi Anda harus menulis berlebihan xdengan nilai baru (yaitu tanpa NaNs ...) . Bisakah Anda memberikan info lebih lanjut mengapa ini bisa terjadi?
jmetz
5
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.
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:
====================1DCase:====================Input:[1400.1500.1600. nan nan nan 1700.]
dropna:[1400.1500.1600.1700.]====================2DCase:====================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))]for2D:====================Input:[[1400.1500.1600.][ nan 0. nan][1700.1800. nan]]
dropna:[1400.1500.1600.1700.]
Selamat datang di SO! Solusi yang Anda usulkan tidak menjawab masalah: solusi Anda menggantikan NaNsejumlah besar, sedangkan OP diminta untuk sepenuhnya menghapus elemen.
Dermaga Paolo
0
Ini adalah pendekatan saya untuk menyaring ndarray "X" untuk NaNs dan infs,
Saya membuat peta baris tanpa NaNdan apa pun infsebagai berikut:
@ 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:
Jawaban:
Jika Anda menggunakan numpy untuk array Anda, Anda juga dapat menggunakan
Setara
[Terima kasih sudah menambahkan singkatan yang ditambahkan]
Penjelasan
Fungsi dalam,
numpy.isnan
mengembalikan array boolean / logis yang memiliki nilai diTrue
mana-mana yangx
bukan-angka. Seperti yang kita inginkan sebaliknya, kita menggunakan operator logical-not,~
untuk mendapatkan array denganTrue
s di mana-mana yangx
merupakan angka yang valid.Terakhir kami menggunakan array logis ini untuk mengindeks ke dalam array asli
x
, untuk mengambil hanya nilai-nilai non-NaN.sumber
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, ketahuilahnumpy.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)
berfungsi baik untuk daftar dan array numpy karena v! = v hanya untuk NaN
sumber
x
ditentukan sekali sebagai lawan dari solusi jenisx[~numpy.isnan(x)]
. Ini nyaman ketikax
didefinisikan oleh ekspresi panjang dan Anda tidak ingin mengacaukan kode dengan membuat variabel sementara untuk menyimpan hasil dari ekspresi panjang ini.Coba ini:
Untuk lebih lanjut, baca tentang Pemahaman Daftar .
sumber
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.
sumber
Melakukan hal di atas:
atau
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
sumber
x
dengan nilai baru (yaitu tanpa NaNs ...) . Bisakah Anda memberikan info lebih lanjut mengapa ini bisa terjadi?Seperti yang ditunjukkan oleh orang lain
bekerja. Tapi itu akan menimbulkan kesalahan jika tipe numpy bukan tipe data asli, misalnya jika objek. Dalam hal ini Anda dapat menggunakan panda.
sumber
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
.Hasil:
sumber
Jika Anda menggunakan
numpy
sumber
Cara paling sederhana adalah:
Dokumentasi: https://docs.scipy.org/doc/numpy/reference/generated/numpy.nan_to_num.html
sumber
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 puninf
sebagai berikut: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
berisi X tanpaNaN
atauinf
.sumber
@ 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:
Lihat lebih detail di sini .
sumber