Pengindeksan logika

Mengganti if di dalam perulangan dengan masker logika pada array.

Daftar isi

Setiap ekspresi relasional seperti v > 10 pada MATLAB menghasilkan array logika yang berukuran sama dengan operannya, dan array itu dapat dipakai langsung sebagai indeks untuk mengambil maupun mengubah elemen terpilih. Topik ini membahas pembentukan array logika tersebut sebagai masker, penggunaan masker sebagai indeks, penugasan selektif pada sebagian elemen, kombinasi masker dengan operator & dan |, serta posisi fungsi find terhadap masker. Seluruh pola tersebut kemudian diterapkan untuk membersihkan pencilan dari data pengukuran suhu. Hasil yang diperoleh adalah pola pengganti if di dalam perulangan: penyaringan data menjadi satu operasi array yang tidak memuat pencacah.

Ekspresi relasional menghasilkan array logika#

Operator relasional >, <, >=, <=, ==, dan ~= mengevaluasi pasangan elemen yang seposisi, lalu menghasilkan array bertipe logical yang berisi nilai benar atau salah pada tiap posisi. Ukuran hasil selalu mengikuti ukuran operannya, sehingga sebuah vektor beranggota enam menghasilkan masker beranggota enam juga. Sifat ini menjadikan ekspresi relasional sebagai bahan mentah penyaringan data.

matlab Ekspresi relasional menghasilkan array logika
v = [4 12 7 20 9 15];
masker = v > 10;
disp(masker);
disp(class(masker));
fprintf('banyak elemen di atas 10: %d\n', sum(masker));
text Keluaran
  0  1  0  1  0  1
logical
banyak elemen di atas 10: 3

Masker bernilai benar tepat pada posisi 12, 20, dan 15, yaitu elemen yang melampaui sepuluh. Kelasnya adalah logical, bukan angka biasa, meskipun nilainya tampil sebagai 0 dan 1. Penjumlahan masker menghasilkan tiga karena nilai benar dihitung sebagai satu, sehingga pola sum(masker) menjadi cara ringkas menghitung banyak kejadian tanpa perulangan. Pada data pengukuran, hitungan semacam ini langsung menjawab pertanyaan seperti berapa banyak pencatatan yang melewati ambang batas.

Masker sebagai indeks dan penugasan selektif#

Array logika dapat ditempatkan di dalam tanda kurung indeks pada dua peran. Sebagai indeks pembacaan, v(masker) mengembalikan elemen yang posisinya bernilai benar, dalam urutan aslinya. Sebagai indeks penugasan, sisi kiri berbentuk v(kondisi) = nilai mengganti hanya elemen yang lolos seleksi tanpa mengubah ukuran array.

matlab Masker sebagai indeks pembacaan
v = [4 12 7 20 9 15];
disp(v(masker));
disp(v(v > 10));
text Keluaran
   12   20   15
   12   20   15
matlab Penugasan selektif pada sebagian elemen
w = [5 -3 12 -8 9 -1 14];
w(w < 0) = 0;
disp(w);
text Keluaran
    5    0   12    0    9    0   14

Pembacaan dengan variabel masker dan pembacaan dengan ekspresi langsung menghasilkan keluaran yang sama, sehingga variabel masker perlu disimpan hanya ketika dipakai berulang. Penugasan selektif pada w menjadikan nol seluruh elemen negatif dalam satu pernyataan. Padanan penugasan selektif pada bahasa pemrograman umum adalah perulangan dengan percabangan if di dalamnya, yang memeriksa tiap elemen satu per satu sebelum mengganti nilainya. Pada MATLAB, pemeriksaan dan penggantian itu menjadi tugas mesin operator indeks, bukan tugas pencacah yang ditulis tangan.

Kombinasi masker dengan & dan |#

Masker gabungan dibentuk dengan operator logika per elemen & (dan), | (atau), serta ~ (tidak). Ketiganya bekerja pasangan demi pasangan sebagaimana operator aritmetika bertitik, sehingga masker hasil berukuran sama dengan operannya. Prioritas operator relasional lebih tinggi daripada & dan |, sehingga v > 5 & v < 20 terbaca sebagai kombinasi dua masker tanpa perlu tanda kurung.

matlab Kombinasi masker dengan & , | , dan ~
v = [4 12 7 20 9 15];
disp(v > 5 & v < 20);
disp(v < 5 | v > 15);
disp(~(v > 10));
text Keluaran
  0  1  1  0  1  1
  1  0  0  1  0  0
  1  0  1  0  1  0

Masker pertama bernilai benar pada elemen yang berada di antara lima dan dua puluh, masker kedua pada elemen di luar rentang itu, dan masker ketiga merupakan kebalikan dari v > 10. Operator ~ membalik setiap posisi satu per satu, yang berguna ketika data yang baik justru yang tidak memenuhi syarat penolakan.

Operator hubung singkat && dan || tidak dapat menggantikan & dan | karena keduanya dirancang hanya untuk operan skalar. Pada MATLAB, pernyataan berikut ditolak dengan error yang menyatakan operan && dan || harus dapat dikonversi menjadi nilai skalar logis.

matlab
% tidak-dijalankan
% MATLAB menolak kombinasi masker dengan operator hubung singkat.
masker_gabungan = (v > 5) && (v < 20)

GNU Octave yang dipakai untuk memverifikasi contoh jalur ini justru menerima pernyataan tersebut tanpa error. Octave mereduksi array menjadi satu nilai kebenaran yang setara dengan all(v > 5) && all(v < 20). Akibatnya, tidak ada error untuk ditangkap, dan hasilnya berupa skalar tunggal yang tidak sesuai maksud per elemen. Perbedaan perilaku MATLAB dan Octave inilah alasan blok ditandai tidak-dijalankan. Kesimpulan praktisnya tetap sama pada kedua implementasi: gunakan &, |, dan ~ untuk masker, serta sisihkan && dan || untuk percabangan yang operannya memang skalar.

find dan posisinya terhadap masker#

Fungsi find mengembalikan posisi elemen yang lolos, bukan nilainya. Pada kasus pembacaan, v(find(v > 10)) identik dengan v(v > 10), sehingga find bukan alat penyaringan yang lebih unggul. Fungsi ini justru dipakai ketika posisi elemen menjadi data yang dibutuhkan: indeks kemunculan pertama, hitungan aritmetika atas posisi, atau pasangan baris-kolom pada matriks.

matlab find mengembalikan posisi elemen yang lolos
v = [4 12 7 20 9 15];
idx = find(v > 10);
disp(idx);
disp(v(idx));
M = [12 5 30; 8 22 14; 27 3 18];
[baris, kolom] = find(M > 20);
disp(baris);
disp(kolom);
text Keluaran
   2   4   6
   12   20   15
   3
   2
   1
   1
   2
   3

Indeks [2 4 6] menunjuk elemen 12, 20, dan 15, dan pengindeksan ulang dengan v(idx) menghasilkan nilai yang sama dengan masker. Pada matriks M, tiga elemen melampaui dua puluh dan find melaporkannya sebagai pasangan baris-kolom. Nilai 30 berada pada baris pertama kolom ketiga, 22 pada baris kedua kolom kedua, dan 27 pada baris ketiga kolom pertama. Urutan laporan mengikuti pengindeksan linear kolom demi kolom, sebagaimana dibahas pada topik pengindeksan. Ketika hanya kemunculan pertama yang dicari, idx(1) atau find(kondisi, 1) memberikannya tanpa memindai sisanya secara manual.

Membersihkan pencilan data suhu#

Data pengukuran nyata kerap memuat pencilan (outlier), yaitu nilai yang menyimpang jauh dari rentang wajar akibat gangguan pencatatan. Pembersihannya memadukan seluruh pola topik ini: syarat kelayakan ditulis sebagai masker, masker dibalik dengan ~ untuk menandai data yang sah, lalu data diindeks dengan masker itu.

matlab bersih_suhu.m
% bersih_suhu.m: membuang pencilan dari catatan suhu sensor

% sepuluh pencatatan suhu lingkungan dalam derajat Celsius
suhu = [21.2 20.8 22.1 19.9 21.5 35.7 20.9 21.0 4.2 21.3];

% rentang wajar menurut lembar data sensor: 15 sampai 30 derajat Celsius
luar = suhu < 15 | suhu > 30;

% elemen yang memenuhi ~luar dipertahankan sebagai data bersih
bersih = suhu(~luar);

fprintf('banyak pencatatan          : %d\n', numel(suhu));
fprintf('banyak pencilan dibuang    : %d\n', sum(luar));
fprintf('nilai pencilan             : %.1f, %.1f\n', suhu(luar));
fprintf('rerata sebelum dibersihkan : %.3f\n', mean(suhu));
fprintf('rerata sesudah dibersihkan : %.3f\n', mean(bersih));
text Keluaran
banyak pencatatan          : 10
banyak pencilan dibuang    : 2
nilai pencilan             : 35.7, 4.2
rerata sebelum dibersihkan : 20.860
rerata sesudah dibersihkan : 21.088

Dua pencilan terdeteksi: 35.7 yang melampaui batas atas dan 4.2 yang jatuh di bawah batas bawah. Rerata sebelum pembersihan tertarik menjadi 20.860 oleh kedua nilai ekstrem itu, sedangkan rerata data bersih berada di 21.088 yang lebih dekat ke pusat data sesungguhnya di sekitar 21 derajat. Skrip tidak memuat satu pun perulangan: pemeriksaan, penghitungan, dan pengambilan nilai pencilan semuanya berjalan melalui masker. Ambang batas pada contoh ini berasal dari rentang kerja sensor. Pada kasus tanpa lembar data, ambang dapat ditetapkan dari statistik data itu sendiri dengan fungsi agregat yang dibahas pada topik fungsi agregat.

Kesalahan umum#

  • Memakai && atau || untuk menggabungkan masker. MATLAB menolak pernyataan itu karena kedua operator hanya menerima operan skalar, sedangkan Octave menerimanya dengan hasil skalar yang menyesatkan. Gunakan & dan | yang bekerja per elemen.
  • Menulis = ketika yang dimaksud adalah ==. Pernyataan v = 10 menimpa seluruh variabel v dengan satu angka, sedangkan v == 10 menghasilkan masker yang membandingkan tiap elemen. Kekeliruan ini merusak data sebelum sempat terdeteksi oleh pemeriksaan lain.
  • Mengharapkan v(v > 10) mengembalikan posisi. Hasilnya adalah nilai elemen yang lolos seleksi, dan posisinya diperoleh dari find(v > 10). Kebiasaan membedakan keduanya sejak awal menghemat penelusuran ketika hasil penyaringan terasa janggal.

Ringkasan#

  • Ekspresi relasional menghasilkan array bertipe logical yang berukuran sama dengan operannya, dan sum(masker) menghitung banyak elemen yang lolos.
  • Masker berfungsi sebagai indeks pembacaan yang mengambil elemen terpilih maupun indeks penugasan yang mengganti elemen terpilih di tempat.
  • Kombinasi masker memakai &, |, dan ~ yang bekerja per elemen, bukan && dan || yang terbatas pada skalar.
  • find melengkapi masker ketika posisi elemen yang dibutuhkan, dan pembersihan pencilan data memadukan keempat pola dalam satu skrip tanpa perulangan.

Referensi#