Semua teknik filter pada chapter-chapter sebelumnya — pelanggan[mask], isin(), between(), sampai query() — berdiri di atas satu mekanisme yang sama: boolean mask. Boolean mask adalah Series berisi nilai True dan False yang sejajar dengan index DataFrame. Pandas membaca mask tersebut untuk memutuskan baris mana yang ditampilkan dan baris mana yang dibuang. Chapter ini membedah mask secara langsung, sehingga kita dapat merancang filter apa pun dan mendiagnosis filter yang memberikan hasil tak terduga.

Perbandingan Menghasilkan Series Boolean #

Setiap perbandingan pada Series menghasilkan Series baru bertipe bool. Ekspresi pelanggan["umur"] >= 30 tidak mengembalikan angka, melainkan enam nilai True/False yang posisinya mengikuti index pelanggan. Panjang mask selalu sama dengan jumlah baris data, dan index mask selalu sama dengan index data aslinya. Dua sifat inilah yang membuat mask bisa “ditempelkan” kembali ke DataFrame tanpa kehilangan kesesuaian baris.

Memilih Baris dengan Mask #

Ketika mask diberikan ke tanda kurung siku, pandas menampilkan baris yang mask-nya True dan membuang baris yang mask-nya False. Penyelarasan dilakukan berdasarkan index, bukan berdasarkan posisi, sehingga data dengan index tak berurutan tetap terpilih dengan benar. Hasil seleksi adalah DataFrame baru berisi salinan baris yang lolos, sesuai perilaku Copy-on-Write pandas 3.0. Penulisan pelanggan[mask] setara dengan pelanggan.loc[mask]; bentuk .loc dibutuhkan ketika kita sekaligus ingin memilih kolom tertentu.

Memeriksa dan Menghitung Mask #

Mask yang belum dipakai pun sudah memberi informasi. Method mask.sum() menghitung jumlah nilai True karena Python memperlakukan True sebagai angka 1 dan False sebagai 0. Fungsi len(mask) tetap menghitung panjang penuh, sehingga perbandingan keduanya langsung menunjukkan berapa banyak baris yang lolos. Operator ~ membalik mask, sementara mask.any() menjawab “apakah ada baris yang lolos” dan mask.all() menjawab “apakah semua baris lolos”. Kombinasi sederhana ini biasa dipakai untuk memeriksa filter sebelum hasilnya dianalisis lebih jauh.

Mask di Balik isin(), between(), dan query() #

Method isin() dan between() tidak melakukan hal lain selain menyusun mask untuk kita. Keduanya mengembalikan Series boolean yang bisa dicetak, dihitung, dibalik, dan digabung seperti mask buatan manual. Method query() juga berakhir di tempat yang sama: string ekspresi diurai, diubah menjadi mask, lalu mask tersebut dipakai untuk memilih baris. Dengan demikian, boolean indexing adalah fondasi tunggal bagi semua gaya filter yang sudah kita pelajari, dan menguasainya berarti menguasai semuanya sekaligus.

Contoh Lengkap dan Bedah Kode #

Skrip berikut menampilkan mask secara utuh sebelum dipakai, lalu menghitungnya dan menerapkannya pada DataFrame.

python
import pandas as pd

pelanggan = pd.DataFrame({
    "nama": ["Budi", "Siti", "Dewi", "Andi", "Rina", "Tono"],
    "kota": ["Jakarta", "Bandung", "Jakarta", "Surabaya", "Bandung", "Jakarta"],
    "umur": [34, 29, 41, 23, 37, 25],
    "total_belanja": [1250000, 540000, 2100000, 320000, 870000, 450000],
})

mask = pelanggan["umur"] >= 30
print("Isi mask:")
print(mask)
print()

print("dtype mask:", mask.dtype)
print("Jumlah True:", mask.sum())
print("Panjang mask:", len(mask))
print()

print("Baris yang lolos filter:")
print(pelanggan[mask])
print()

print("Kolom nama milik baris yang lolos:")
print(pelanggan.loc[mask, "nama"])

Output yang Dihasilkan:

text
Isi mask:
0     True
1    False
2     True
3    False
4     True
5    False
Name: umur, dtype: bool

dtype mask: bool
Jumlah True: 3
Panjang mask: 6

Baris yang lolos filter:
   nama     kota  umur  total_belanja
0  Budi  Jakarta    34        1250000
2  Dewi  Jakarta    41        2100000
4  Rina  Bandung    37         870000

Kolom nama milik baris yang lolos:
0    Budi
2    Dewi
4    Rina
Name: nama, dtype: str

Mari kita telaah baris demi baris:

  1. Baris 3-8 (pelanggan = pd.DataFrame({...})): tabel enam baris dengan index default 0 sampai 5 disiapkan sebagai bahan latihan.
  2. Baris 10 (mask = pelanggan["umur"] >= 30): perbandingan menghasilkan Series bool dengan True pada index 0, 2, dan 4, yaitu Budi (34), Dewi (41), dan Rina (37).
  3. Baris 15-17 (mask.dtype, mask.sum(), len(mask)): tipe mask adalah bool, jumlah True adalah 3, dan panjang penuh mask adalah 6; selisih keduanya menunjukkan tiga baris tersaring.
  4. Baris 21 (pelanggan[mask]): hanya baris dengan True yang tampil, dan index hasilnya mempertahankan label asli 0, 2, dan 4 — bukan dinomori ulang.
  5. Baris 25 (pelanggan.loc[mask, "nama"]): satu akses .loc memilih kolom nama dari baris yang lolos dan menghasilkan Series bertipe str.

Perhatikan kembali bahwa index hasil seleksi adalah 0, 2, dan 4, bukan 0, 1, dan 2. Index yang dipertahankan itu penting saat hasil seleksi digabungkan dengan data lain, karena penyelarasan pandas bekerja pada label. Dengan pemahaman mask yang solid, kita siap untuk topik terakhir Section ini: mengubah nilai DataFrame dengan aman tanpa terjebak chained indexing.

Referensi resmi: Indexing and selecting data dan 10 minutes to pandas .