Setelah deteksi pada bab-bab sebelumnya, tindakan paling umum adalah membuang nilai yang tidak valid dari array. Caranya memadukan dua materi: mask boolean dari Chapter Boolean Indexing sebagai selektor, dan detektor np.isnan/np.isfinite dari Chapter isfinite, isnan, dan isinf sebagai pembuat mask.
Bab ini membahas filtering satu dimensi, perbedaan membuang nan saja versus membuang nan sekaligus inf, dua sifat penting hasil filter (selalu satu dimensi dan selalu copy), sampai penyaringan baris pada array dua dimensi.
Membuang NaN dengan ~np.isnan #
import numpy as np
suhu = np.array([27.5, np.nan, 29.1, np.nan, 26.8])
bersih = suhu[~np.isnan(suhu)]
print(bersih)
print(bersih.shape)
print(np.nanmean(suhu) == bersih.mean())Output yang Dihasilkan:
[27.5 29.1 26.8]
(3,)
TrueMari kita bedah:
- Baris 4 (
~np.isnan(suhu)):np.isnanmenandai posisinan, lalu~membalik mask sehinggaTrueberarti “nilai layak simpan”. - Baris 4 (
suhu[mask]): mask dipakai sebagai selektor; hasilnya hanya tiga pembacaan valid, dalam urutan aslinya. - Baris 6: pembuktian silang —
nanmeanpada data asli sama persis denganmeanpada data hasil filter (True). Dua jalan berbeda, satu angka yang sama; pola ini dibahas juga pada Chapter NaN-aware Aggregation.
isfinite Membuang NaN dan inf Sekaligus #
Bila data berpotensi memuat tak hingga, filter berbasis isnan tidak cukup — inf lolos begitu saja:
import numpy as np
a = np.array([1.5, np.nan, np.inf, 2.0, -np.inf])
print(a[~np.isnan(a)])
print(a[np.isfinite(a)])Output yang Dihasilkan:
[ 1.5 inf 2. -inf]
[1.5 2. ]Penjelasan singkat:
- Baris 4 (
~np.isnan(a)): hanyananyang dibuang;infdan-infmasih ikut dalam hasil. - Baris 5 (
np.isfinite(a)): mask iniTruehanya untuk nilai berhingga, sehingganan,inf, dan-inftersaring sekaligus.
Pemilihan filter dapat diringkas sebagai berikut:
- Data hanya berpotensi memuat
nan→ gunakana[~np.isnan(a)]. - Data bisa memuat
inf(misalnya dari pembagian nol) → gunakana[np.isfinite(a)]. - Ingin tahu dulu berapa yang akan dibuang → hitung dengan pola Chapter Memeriksa Nilai Valid:
(~np.isfinite(a)).sum().
Hasil Filter Selalu 1-D dan Berupa Copy #
Boolean mask pada array dua dimensi tidak mengembalikan matriks — hasilnya selalu array satu dimensi berisi elemen yang lolos, dan selalu array baru:
import numpy as np
m = np.array([[1.0, np.nan], [np.inf, 4.0]])
hasil = m[np.isfinite(m)]
print(hasil)
print(hasil.shape)
print(np.shares_memory(hasil, m))Output yang Dihasilkan:
[1. 4.]
(2,)
FalseMari kita telaah:
- Baris 4 (
m[np.isfinite(m)]): mask dua dimensi memilih elemen yang lolos menyusuri baris, dari kiri ke kanan;1.0dan4.0tersisa. - Baris 5: bentuk
(2,)menegaskan hasil filter selalu satu dimensi — baris dan kolom asal tidak dipertahankan. - Baris 6 (
np.shares_memory(...)):Falseberarti hasil adalah array baru (copy); mengubahhasiltidak memengaruhim. Perbedaan view dan copy dibahas penuh pada Chapter View vs Copy.
Menyaring Baris pada Array Dua Dimensi #
Untuk data tabel — misalnya log stasiun cuaca dengan beberapa kolom pengukuran — yang biasanya dibuang adalah baris, bukan elemen lepas. Mask baris dibentuk dengan any(axis=1) atau all(axis=1):
import numpy as np
pengukuran = np.array([
[27.5, 28.1, 26.9],
[np.nan, np.nan, np.nan],
[28.3, np.nan, 27.7],
])
print(np.isnan(pengukuran).any(axis=1))
print(pengukuran[~np.isnan(pengukuran).any(axis=1)])
print(pengukuran[~np.isnan(pengukuran).all(axis=1)])Output yang Dihasilkan:
[False True True]
[[27.5 28.1 26.9]]
[[27.5 28.1 26.9]
[28.3 nan 27.7]]Mari kita bedah:
- Baris 3-7: matriks tiga baris pembacaan; baris tengah tidak terisi sama sekali, baris ketiga kehilangan satu pembacaan.
- Baris 8 (
any(axis=1)): tiap baris diperiksa “apakah memuat minimal satunan” — hasilnya[False True True]. - Baris 9: dengan negasi, hanya baris pertama yang lolos; satu
nansaja cukup untuk membuang seluruh barisnya. - Baris 10 (
all(axis=1)): kebalikannya — hanya baris yangnandi semua kolom yang dibuang, sehingga baris ketiga tetap dipertahankan walau satu pembacaannya hilang.
| Ekspresi | Baris yang dibuang |
|---|---|
a[~np.isnan(a).any(axis=1)] | baris yang memuat minimal satu NaN |
a[~np.isnan(a).all(axis=1)] | baris yang NaN di semua kolom |
Filtering bukan satu-satunya pilihan: bila nilai yang hilang masih bisa digantikan dengan angka yang masuk akal, bab berikutnya — Mengganti Nilai Tertentu — menunjukkan caranya.