Pandas query: Filter Data dengan Ekspresi Ringkas
TL;DR
df.query() adalah metode pandas buat filter baris DataFrame pakai ekspresi berupa string, misalnya df.query("harga > 50000"). Cara ini lebih ringkas dan gampang dibaca daripada boolean mask waktu kondisinya banyak. Kamu bisa nyambungin variabel dari luar pakai tanda @, dan gabungin banyak kondisi pakai and, or, serta in. Buat filter sederhana satu kondisi, boolean mask biasa masih lebih cepat dan lebih fleksibel.
df.query() adalah metode pandas buat filter baris DataFrame pakai ekspresi string. Contoh: df.query("harga > 50000") ngambil semua baris yang harganya di atas 50 ribu.
Kelebihannya kelihatan waktu kondisinya banyak. Boolean mask yang panjang penuh kurung dan nama DataFrame berulang. query() bikin filter yang sama kebaca kayak kalimat biasa.
Di bawah ini aku bahas cara pakainya, cara nyambungin variabel, filter teks, dan kapan sebaiknya balik ke boolean mask. Semua pakai dataset transaksi toko_berkah.
Apa itu pandas query?
pandas query adalah metode DataFrame.query() yang nyaring baris berdasarkan ekspresi yang kamu tulis sebagai string. Di dalam string itu, nama kolom bisa ditulis langsung tanpa awalan df[]. Hasilnya DataFrame baru yang cuma berisi baris yang memenuhi kondisi. Metode ini enak buat filter yang panjang soalnya sintaksnya lebih pendek dan mirip bahasa manusia.
Kalau kamu baru mulai sama seleksi data di pandas, konsep dasarnya ada di glosarium DataFrame.
Gimana cara pakai df.query()?
Tulis kondisinya sebagai string di dalam tanda kurung. Nama kolom langsung, tanpa kutip.
import pandas as pd
df = pd.read_csv("transaksi.csv")
# ambil transaksi di atas 50 ribu
hasil = df.query("harga > 50000")
Bandingin sama boolean mask yang setara:
hasil = df[df["harga"] > 50000]
Dua-duanya ngasih hasil sama. Buat satu kondisi, bedanya tipis. Bedanya baru kerasa waktu kondisinya numpuk.
query() balikin DataFrame baru, data aslinya nggak berubah. Kalau mau simpan hasilnya, tampung di variabel kayak contoh di atas.
Query dengan banyak kondisi
Di sinilah query() menang. Gabungin kondisi pakai and, or, dan not, kata biasa, bukan simbol.
hasil = df.query("harga > 50000 and cabang == 'Depok'")
Bandingin sama boolean mask-nya yang penuh kurung dan pengulangan:
hasil = df[(df["harga"] > 50000) & (df["cabang"] == "Depok")]
Versi query jauh lebih enak dibaca. Nggak ada kurung bertumpuk, nama DataFrame nggak diulang tiga kali. Buat filter dengan 3 kondisi atau lebih, ini beda banget rasanya.
Buat ngecek nilai di dalam daftar, pakai in:
hasil = df.query("cabang in ['Depok', 'Bekasi']")
Rentang angka juga bisa ditulis berantai kayak matematika:
hasil = df.query("20000 <= harga <= 100000")
Cara pakai variabel dari luar dengan @
Sering kamu mau filter pakai nilai dari variabel, bukan angka yang diketik langsung. Tandain variabel itu pakai @.
batas = 50000
kota = "Depok"
hasil = df.query("harga > @batas and cabang == @kota")
Tanpa @, pandas bakal nyari kolom bernama "batas" dan bikin error soalnya kolom itu nggak ada. Tanda @ ngasih tau pandas kalau itu variabel Python dari luar, bukan nama kolom.
Ini yang bikin query() kepakai di fungsi. Kamu bisa oper batas filter sebagai parameter, terus pakai @ di dalam query. Rapi buat kode yang dipakai ulang.
Cara filter kolom teks di query
Nilai teks harus dibungkus kutip di dalam string query. Karena string luar udah pakai kutip ganda, isi teksnya pakai kutip tunggal.
hasil = df.query("metode_bayar == 'QRIS'")
Buat filter berdasarkan potongan teks, kolomnya harus kamu panggil metode string-nya lewat backtick atau pakai pendekatan lain. Cara paling aman buat pencarian teks parsial justru boolean mask:
# cari produk yang mengandung kata 'minyak'
hasil = df[df["produk"].str.contains("minyak", case=False)]
query() kurang nyaman buat str.contains dan operasi teks rumit. Buat itu, boolean mask lebih jelas. Aku bahas seleksi teks lebih lanjut di Pandas: Filter Baris Berdasarkan Kondisi.
query() vs boolean mask, mana lebih baik?
Nggak ada yang menang mutlak. Ini pembagian yang aku pakai.
| Situasi | Pilih |
|---|---|
| Banyak kondisi and/or | query() |
| Filter pakai variabel | query() dengan @ |
| Satu kondisi sederhana | boolean mask |
| Operasi teks (str.contains) | boolean mask |
| Nama kolom ada spasi | boolean mask (lebih aman) |
Kalau nama kolomnya ada spasi, query() masih bisa pakai backtick, misalnya df.query("`harga satuan` > 5000"), tapi gampang bikin bingung. Buat kolom kayak gitu, boolean mask lebih aman. Perbandingan seleksi baris dengan loc dan iloc ada di Pandas loc vs iloc.
Contoh kasus: filter transaksi toko_berkah
Dataset toko_berkah punya 8.412 baris transaksi. Aku mau jawab satu pertanyaan: berapa transaksi besar (di atas 100 ribu) yang dibayar QRIS di cabang Depok selama Juni.
batas = 100000
besar = df.query(
"harga > @batas "
"and metode_bayar == 'QRIS' "
"and cabang == 'Depok'"
)
print(len(besar))
Hasilnya 312 transaksi. Tiga kondisi, satu string yang kebaca jelas. Versi boolean mask-nya butuh tiga kurung dan tiga kali nyebut df, jauh lebih ramai.
Angka yang menarik muncul waktu aku bandingin: dari 312 transaksi besar QRIS di Depok, rata-rata nilainya Rp 187.000. Sementara transaksi besar yang dibayar tunai di cabang sama cuma 47 baris dengan rata-rata Rp 142.000.
Jadi di Depok, pelanggan yang belanja gede cenderung bayar QRIS, dan nilai belanjanya pun lebih tinggi 32%. Temuan kecil, tapi ngedukung keputusan mereka naruh promo QRIS di cabang itu.
Kesalahan umum waktu pakai df.query()
Lupa tanda @ buat variabel. Nulis query("harga > batas") bikin pandas nyari kolom "batas" dan error. Variabel Python harus pakai @batas.
Salah jenis kutip. Kalau string luar pakai kutip ganda, nilai teks di dalam harus kutip tunggal. Kalau ketuker, Python bingung mana ujung stringnya.
Pakai simbol & dan | kayak boolean mask. Di dalam query(), pakai kata and dan or, bukan simbol. Simbol itu buat boolean mask, bukan buat string query.
Ngarep query() ngubah data asli. query() balikin salinan, DataFrame asli nggak berubah. Tampung hasilnya ke variabel baru.
Nama kolom ada spasi tapi lupa backtick. Kolom "harga satuan" harus ditulis `harga satuan` pakai backtick, kalau nggak query-nya error.
FAQ
Apakah df.query() lebih cepat dari boolean mask?
Buat DataFrame kecil, boolean mask biasanya sedikit lebih cepat soalnya query() perlu waktu buat mem-parsing string ekspresinya. Buat DataFrame besar dengan jutaan baris, query() bisa lebih cepat kalau pandas pakai mesin numexpr di belakang. Tapi bedanya jarang jadi masalah nyata. Pilih berdasarkan mana yang lebih kebaca, bukan kecepatan, kecuali kamu beneran ngukur ada bottleneck.
Gimana cara pakai df.query() dengan nama kolom yang ada spasi?
Bungkus nama kolomnya pakai backtick, bukan kutip. Contoh: df.query("`harga satuan` > 5000"). Backtick ngasih tau pandas kalau seluruh teks di dalamnya satu nama kolom, walaupun ada spasi. Ini fitur yang lumayan baru di pandas, jadi pastiin versi pandas kamu cukup baru. Kalau ribet, ganti nama kolomnya dulu jadi tanpa spasi pakai rename, itu lebih aman jangka panjang.
Bisa nggak df.query() dipakai buat filter teks yang mengandung kata tertentu?
Bisa tapi kurang nyaman. query() paling enak buat perbandingan sama-dengan atau angka. Buat nyari baris yang teksnya mengandung kata tertentu, boolean mask dengan str.contains jauh lebih jelas: df[df["produk"].str.contains("minyak")]. Aturan praktisku: pakai query() buat kondisi angka dan kesamaan persis, pakai boolean mask buat pencarian teks parsial dan operasi string.
Apa bedanya query() dan filter() di pandas?
Beda fungsi. query() nyaring baris berdasarkan isi datanya, misalnya harga di atas sekian. filter() nyaring kolom atau baris berdasarkan namanya, bukan isinya, misalnya ambil semua kolom yang namanya mengandung kata "tanggal". Jadi query() buat memilih baris berdasarkan nilai, filter() buat memilih kolom berdasarkan label. Keduanya beda tujuan dan jarang saling gantiin.
Kenapa df.query() saya error "name is not defined"?
Paling sering gara-gara kamu masukin variabel Python tanpa tanda @. Kalau kamu tulis df.query("harga > batas") sementara batas itu variabel di kodemu, pandas nyangka "batas" nama kolom, nggak nemu, lalu error. Perbaiki jadi df.query("harga > @batas"). Tanda @ wajib buat semua variabel yang datang dari luar string query.
Penutup
Ringkasnya:
- df.query() nyaring baris pakai ekspresi string yang kebaca kayak kalimat.
- Menang buat kondisi banyak dan buat filter pakai variabel lewat tanda @.
- Buat satu kondisi sederhana atau pencarian teks, boolean mask masih lebih pas.
Buka DataFrame kamu, ambil filter boolean mask paling panjang yang kamu punya, tulis ulang jadi satu df.query(). Rasain sendiri bedanya waktu dibaca minggu depan.
Mau dalamin cara seleksi baris yang lain? Lanjut ke Pandas: Filter Baris Berdasarkan Kondisi. Dokumentasi resmi query() ada di dokumentasi pandas.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Artikel terkait
NumPy reshape: Ubah Bentuk Array (2026)
Fungsi reshape di NumPy ngatur ulang bentuk array tanpa ngubah datanya. Ini cara pakainya, arti angka -1, dan cara ngeflat array.
NumPy Array: Dasar-Dasar untuk Analis Data (2026)
NumPy array bikin hitungan data di Python jauh lebih cepat dari list biasa. Ini dasar bikin, slicing, dan operasi array buat analis.
Alternatif iterrows yang Lebih Cepat di Pandas
iterrows nyaman ditulis tapi lambat. Ini urutan alternatif iterrows di pandas dari yang tercepat, plus benchmark biar kamu tau kapan pakai yang mana.