Pembersihan data jarang selesai hanya dengan “buang semua nan”. Pertanyaan analitis biasanya lebih spesifik: “pembacaan suhu mana yang valid sekaligus berada dalam rentang normal?”, atau “jam mana yang suhunya layak dihitung tapi kelembapannya tidak?”. Kebutuhan semacam ini dijawab dengan mask — array boolean yang disusun dari beberapa kondisi — serta kemampuan memakai satu mask lintas array.
Bab ini menyusun mask bernama dari gabungan kondisi, memakai ulang satu mask untuk dua array yang sejajar, dan menutup dengan sekilas masked array (np.ma) sebagai alternatif bawaan NumPy untuk data bertanda.
Mask Bernama dari Beberapa Kondisi #
import numpy as np
suhu = np.array([27.5, 31.2, np.nan, 26.8, 35.4, np.nan, 29.9])
valid = np.isfinite(suhu)
normal = valid & (suhu > 26.0) & (suhu < 33.0)
print(valid)
print(normal)
print(suhu[normal])Output yang Dihasilkan:
[ True True False True True False True]
[ True True False True False False True]
[27.5 31.2 26.8 29.9]Mari kita bedah:
- Baris 4 (
valid = np.isfinite(suhu)): mask dasar kualitas data — lima dari tujuh pembacaan berhingga. - Baris 5 (
normal = valid & ... & ...): tiga kondisi digabung dengan&, masing-masing wajib dalam tanda kurung (aturan dari Chapter Boolean Indexing). - Baris 6-8: mask bernama dapat dicetak dan diperiksa lebih dulu, lalu dipakai sebagai selektor — empat pembacaan lolos,
35.4tersaring karena melewati batas atas.
Mencantumkan valid secara eksplisit memang tidak selalu mengubah hasil — perbandingan apa pun dengan nan menghasilkan False — tetapi pola ini tetap disarankan karena dua alasan:
- Niat jelas terbaca: pembaca kode langsung tahu bahwa kualitas data adalah bagian dari syarat, bukan efek samping.
- Tahan perubahan: bila suatu saat kondisi batas berubah menjadi satu sisi (misalnya hanya
suhu > 26.0), nilaiinftidak tiba-tiba lolos, karenavalidsudah menyaringnya lebih dulu.
Satu Mask untuk Banyak Array #
Saat beberapa sensor merekam pada jam yang sama, posisi ke-i di tiap array mewakili pengukuran yang sama. Mask yang dibangun dari satu array bisa dipakai ke array lain yang sejajar, sehingga baris yang hilang dibuang serentak:
import numpy as np
suhu = np.array([27.5, np.nan, 29.1, 31.0, np.nan, 26.8])
kelembapan = np.array([70.0, 72.5, 68.0, 75.0, 71.0, 69.5])
mask_valid = np.isfinite(suhu)
print("suhu :", suhu[mask_valid])
print("kelembapan:", kelembapan[mask_valid])Output yang Dihasilkan:
suhu : [27.5 29.1 31. 26.8]
kelembapan: [70. 68. 75. 69.5]Penjelasan singkat:
- Baris 5 (
mask_valid = np.isfinite(suhu)): mask dibangun dari sensor suhu saja; dua posisi tidak terisi. - Baris 6-7: mask yang sama dipakai ke kedua array — kelembapan pada jam yang bermasalah ikut terbuang agar pasangan data (suhu, kelembapan) tetap cocok.
- Syarat penting: kedua array harus berbentuk sama; mask
(6,)tidak bisa dipakai ke array berukuran(8,).
Pola ini adalah dasar dari seleksi data bersama (join per posisi) dan akan sering muncul ketika beberapa kolom harus dibersihkan secara konsisten.
Sekilas Masked Array #
Boolean indexing selalu mengembalikan array baru yang bentuknya menyusut. Bila bentuk asli harus dipertahankan — misalnya agar hasil bisa diplot atau digabung per posisi — NumPy menyediakan masked array yang menandai elemen bermasalah tanpa membuangnya:
import numpy as np
suhu = np.array([27.5, np.nan, 28.5, 30.0, np.nan, 26.0])
tertutup = np.ma.masked_invalid(suhu)
print(tertutup)
print(tertutup.mean())Output yang Dihasilkan:
[27.5 -- 28.5 30.0 -- 26.0]
28.0Mari kita telaah:
- Baris 4 (
np.ma.masked_invalid(suhu)): elemennan(daninf) ditandai sebagai elemen tertutup, ditampilkan sebagai--; bentuk array tetap(6,). - Baris 6 (
tertutup.mean()): agregasi pada masked array otomatis melewati elemen tertutup, menghasilkan28.0— tanpa mengubah array dan tanpa keluarganan*.
Ringkasan pola masking pada bab ini:
| Ekspresi | Arti |
|---|---|
valid = np.isfinite(suhu) | mask dasar kualitas data |
valid & (suhu > 26.0) & (suhu < 33.0) | irisan tiga kondisi |
suhu[normal] | seleksi nilai yang lolos mask |
kelembapan[mask_valid] | mask satu array dipakai ke array sejajar |
np.ma.masked_invalid(suhu) | menandai tanpa membuang, bentuk tetap |