Filter dengan satu kondisi jarang cukup untuk pekerjaan analisis yang nyata. Tim pemasaran menanyakan pelanggan di Jakarta yang belanjanya di atas 500 ribu, sementara tim produk ingin mengetahui pengguna berusia di bawah 25 tahun atau di atas 35 tahun. Kedua pertanyaan tersebut membutuhkan beberapa kondisi yang digabungkan menjadi satu keputusan True/False untuk setiap baris. Pada Chapter ini kita menggabungkan kondisi dengan operator & (AND), | (OR), dan ~ (NOT), lalu membahas tanda kurung yang wajib ditulis agar hasil filter sesuai harapan.
Tiga Operator Penggabung Kondisi #
Di Python sehari-hari kita menggabungkan kebenaran dengan kata kunci and, or, dan not. Pandas tidak memakai kata kunci tersebut untuk Series dan DataFrame karena kata kunci itu menilai satu nilai tunggal, bukan ribuan baris sekaligus. Sebagai gantinya, pandas memakai operator bitwise yang bekerja baris demi baris secara vectorized: & untuk AND, | untuk OR, dan ~ untuk NOT. Hasilnya selalu Series boolean dengan panjang dan index yang sama seperti data aslinya.
| Operator | Padanan Python | Menghasilkan True bila |
|---|---|---|
& | and | kedua kondisi bernilai True |
| | or | minimal satu kondisi bernilai True |
~ | not | kondisi awal bernilai False |
Setiap perbandingan pada Chapter sebelumnya sudah menghasilkan Series boolean, sehingga operator di atas menerima perbandingan sebagai masukannya. Dua Series boolean yang digabungkan dibandingkan posisi demi posisi berdasarkan index. Pola dasarnya selalu sama: hitung tiap kondisi, bungkus dengan tanda kurung, lalu gabungkan.
Operator & untuk Syarat yang Harus Terpenuhi Semua #
Operator & dipakai ketika sebuah baris harus memenuhi semua syarat sekaligus. Ekspresi (pelanggan["kota"] == "Jakarta") & (pelanggan["total_belanja"] > 500000) bernilai True hanya pada baris yang kotanya Jakarta dan belanjanya di atas 500 ribu. Series hasilnya kemudian diberikan ke pelanggan[...] sebagai mask untuk memilih baris yang lolos. Tanda kurung pada kedua sisi bukan gaya penulisan, melainkan kebutuhan teknis yang kita bedah di bagian bawah chapter ini.
Operator | untuk Alternatif Kondisi #
Operator | memilih baris yang memenuhi minimal satu syarat. Filter (pelanggan["umur"] < 25) | (pelanggan["umur"] > 35) mengambil pengguna di bawah 25 tahun maupun yang sudah melewati 35 tahun, sementara baris di rentang tengah dikesampingkan. Semakin banyak alternatif yang diizinkan, semakin panjang rantai | yang harus ditulis. Chapter berikutnya menyajikan isin() yang meringkas pola seperti ini menjadi satu panggilan method.
Operator ~ untuk Membalik Filter #
Operator ~ membalik seluruh nilai boolean sebuah Series: True menjadi False dan sebaliknya. Pola ~(kondisi) berarti “semua baris kecuali yang memenuhi kondisi”, misalnya ~(pelanggan["kota"] == "Jakarta") untuk mengambil pelanggan di luar Jakarta. Untuk satu kondisi sederhana, hasil ~ setara dengan memakai operator !=. Manfaat ~ baru terasa penuh saat membalik hasil method seperti isin() yang sudah menghasilkan mask jadi, bukan kondisi mentah.
Mengapa Tanda Kurung Wajib Ditulis #
Dalam bahasa Python, operator & dan | memiliki tingkat keutamaan (precedence) yang lebih tinggi daripada operator perbandingan seperti < dan ==. Tanpa tanda kurung, ekspresi pelanggan["umur"] < 25 | pelanggan["umur"] > 35 dibaca Python sebagai pelanggan["umur"] < (25 | pelanggan["umur"]) > 35, sebuah perbandingan berantai. Evaluasi perbandingan berantai tersebut memicu penggabungan and implisit antar Series, sehingga pandas melempar ValueError yang sama seperti pada callout di atas. Dengan tanda kurung di setiap perbandingan, tiap kondisi selesai dihitung menjadi Series boolean terlebih dahulu, lalu operator bitwise menggabungkannya baris demi baris.
Contoh Lengkap dan Bedah Kode #
Skrip berikut menerapkan ketiga operator pada tabel pelanggan yang sama, lengkap dengan hasil filternya.
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_and = (pelanggan["kota"] == "Jakarta") & (pelanggan["total_belanja"] > 500000)
print("AND - Jakarta dan belanja di atas 500 ribu:")
print(pelanggan[mask_and])
print()
mask_or = (pelanggan["umur"] < 25) | (pelanggan["umur"] > 35)
print("OR - umur di bawah 25 atau di atas 35:")
print(pelanggan[mask_or])
print()
mask_not = ~(pelanggan["kota"] == "Jakarta")
print("NOT - di luar Jakarta:")
print(pelanggan[mask_not])Output yang Dihasilkan:
AND - Jakarta dan belanja di atas 500 ribu:
nama kota umur total_belanja
0 Budi Jakarta 34 1250000
2 Dewi Jakarta 41 2100000
OR - umur di bawah 25 atau di atas 35:
nama kota umur total_belanja
2 Dewi Jakarta 41 2100000
3 Andi Surabaya 23 320000
4 Rina Bandung 37 870000
NOT - di luar Jakarta:
nama kota umur total_belanja
1 Siti Bandung 29 540000
3 Andi Surabaya 23 320000
4 Rina Bandung 37 870000Mari kita telaah baris demi baris:
- Baris 3-8 (
pelanggan = pd.DataFrame({...})): kita menyiapkan tabel enam baris berisi nama, kota, umur, dan total belanja sebagai bahan filter. - Baris 10 (
mask_and = ... & ...): dua perbandingan dihitung terlebih dahulu karena masing-masing dibungkus tanda kurung, lalu&menggabungkan keduanya; hanya baris 0 (Budi) dan baris 2 (Dewi) yang memenuhi kedua syarat. - Baris 11-13:
pelanggan[mask_and]menampilkan baris yang lolos, danprint()tanpa argumen mencetak baris kosong sebagai pemisah. - Baris 15 (
mask_or = ... | ...): filter OR mengambil umur di luar rentang 25-35, sehingga baris 2 (Dewi), 3 (Andi), dan 4 (Rina) tampil. - Baris 20 (
mask_not = ~(...)): negasi membalik mask “kota Jakarta” sehingga semua pelanggan non-Jakarta muncul.
Perhatikan bahwa tidak ada filter yang mengubah pelanggan; setiap seleksi menghasilkan DataFrame baru berisi salinan baris yang lolos. Perilaku tersebut berasal dari Copy-on-Write yang selalu aktif di pandas 3.0 dan dibahas mendalam pada chapter terakhir Section ini.
Kondisi kesetaraan yang panjang masih bisa diringkas lagi: isin() menangani daftar nilai sekaligus dan between() menangani rentang nilai. Itulah topik chapter berikutnya. Dokumentasi resmi: Indexing and selecting data
dan 10 minutes to pandas
.