Pembacaan sensor sering membawa kode kegagalan: alat yang gagal mengukur menulis -99, file CSV menandai sel kosong dengan nilai tertentu, atau perhitungan menghasilkan nan dan inf. Chapter NaN dan Infinity membahas penanganannya untuk data float — tetapi ada dua masalah yang tidak terjawab di sana: satu nan saja membuat agregasi ikut menjadi nan, dan array integer sama sekali tidak bisa menyimpan nan.
Masked array dari modul np.ma memecahkan keduanya. Datanya tetap utuh, tetapi setiap elemen dibekali flag boolean — mask — yang menandai elemen tersebut boleh diabaikan. Semua operasi NumPy yang disediakan np.ma menghormati flag itu: elemen yang dimasking tetap tersimpan, namun tidak ikut menghitung.
Membuat Masked Array dengan masked_where #
Fungsi np.ma.masked_where(kondisi, array) memasangkan setiap elemen dengan nilai kondisi. Nilai pengganti kegagalan sensor -99.0 pada contoh berikut tetap tersimpan di dalam data, hanya ditandai:
import numpy as np
pembacaan = np.array([27.5, -99.0, 26.8, 28.1, -99.0])
m = np.ma.masked_where(pembacaan == -99.0, pembacaan)
print(m)
print(m.data)
print(m.mask)Output yang Dihasilkan:
[27.5 -- 26.8 28.1 --]
[ 27.5 -99. 26.8 28.1 -99. ]
[False True False False True]Mari kita bedah:
- Baris 4 (
np.ma.masked_where(...)): kondisipembacaan == -99.0menghasilkan mask boolean, dan fungsi tersebut menyatukannya dengan data menjadi objekMaskedArray. - Baris 5 (
print(m)): elemen yang dimasking ditampilkan sebagai--— tanda bahwa nilainya diabaikan, bukan dihapus. - Baris 6 (
m.data): atributdatamenampung array asli;-99.0masih ada di posisi asalnya. - Baris 7 (
m.mask): mask boolean memetakan posisi yang diabaikan;Trueberarti “jangan ikutkan”.
Operasi Agregasi yang Menghormati Mask #
Manfaat utamanya terasa saat menghitung. Bandingkan rata-rata array biasa yang tercemar nilai sentinel dengan rata-rata masked array:
import numpy as np
pembacaan = np.array([27.5, -99.0, 26.8, 28.1, -99.0])
m = np.ma.masked_where(pembacaan == -99.0, pembacaan)
print(pembacaan.mean())
print(m.mean())
print(m.max())Output yang Dihasilkan:
-23.119999999999997
27.46666666666667
28.1Penjelasannya:
- Baris 5 (
pembacaan.mean()): dua nilai-99.0ikut dihitung, sehingga rata-rata jatuh ke-23.12...— angka yang tidak bermakna untuk suhu. - Baris 6 (
m.mean()): fungsi agregasi versinp.mamenjumlahkan hanya elemen yang tidak dimasking dan membaginya dengan jumlah elemen valid, menghasilkan27.47.... - Baris 7 (
m.max()):maxjuga sadar mask, sehingga-99.0tidak pernah dipilih sebagai nilai terbesar.
masked_invalid untuk nan dan inf #
Untuk data float yang sudah mengandung nan atau inf, fungsi np.ma.masked_invalid memasang mask pada semua nilai tersebut sekaligus:
import numpy as np
f = np.array([1.5, np.nan, 2.5, np.inf])
mf = np.ma.masked_invalid(f)
print(mf)
print(mf.mean())Output yang Dihasilkan:
[1.5 -- 2.5 --]
2.0Bandingkan dengan pendekatan np.nanmean pada Chapter NaN-aware Aggregation: hasil hitungnya sama, tetapi masked array menyimpan flag secara eksplisit, sehingga posisi yang bermasalah tetap dapat diperiksa lewat mf.mask kapan saja.
Ketika Array Integer Tidak Bisa Memuat NaN #
Array integer tidak memiliki representasi nan. NumPy tidak menolak saat kita menulis nan di dalam list — ia diam-diam menaikkan seluruh array menjadi float, dan tipe integer aslinya hilang:
import numpy as np
nilai = np.array([80, 75, 88])
coba = np.array([80, np.nan])
print(coba.dtype)
mn = np.ma.masked_values(nilai, 75)
print(mn)
print(mn.mean())
print(mn.compressed())
print(mn.filled(0))Output yang Dihasilkan:
float64
[80 -- 88]
84.0
[80 88]
[80 0 88]Bedah baris demi baris:
- Baris 4 (
coba.dtype): campuran80dannp.nanmenghasilkan arrayfloat64— integer tidak pernah bisa memuatnan. - Baris 5 (
np.ma.masked_values(nilai, 75)): pada arrayint32asli, nilai yang harus diabaikan ditandai dengan pola nilai tertentu — di sini75sebagai contoh kode kosong. - Baris 7-8: agregasi menghasilkan
84.0dari dua elemen valid saja. - Baris 9 (
mn.compressed()): mengembalikan salinan berisi elemen valid saja, mask beserta elemen tersembunyinya dilepas. - Baris 10 (
mn.filled(0)): mengembalikan array biasa dengan elemen tersembunyi diganti nilai isian0.
Kapan memilih np.ma daripada pendekatan nan? Ringkasnya:
| Situasi | Pendekatan nan | Pendekatan np.ma |
|---|---|---|
| Data float, analisis statistik | np.nanmean dan kawan-kawan cukup | juga bisa, dengan mask eksplisit |
| Data integer bertanda kosong | tidak didukung (nan memaksa float) | satu-satunya pilihan bawaan NumPy |
| Perlu menelusuri posisi bermasalah | via np.isnan terpisah | langsung dari atribut mask |