Penyaringan dengan query mengekspresikan kondisi baris sebagai satu string ekspresi, misalnya df.query("suhu_c > 25"), sehingga gabungan beberapa syarat terbaca seperti kalimat logika. Topik ini membahas sintaks dasar query pada dataset log sensor tiga ruangan, penggunaan variabel python melalui tanda @, pertimbangan kapan query lebih tepat daripada indeks boolean, dan kesalahan penulisan yang paling sering muncul. Setelah membaca, penyaringan berbasis string dapat ditulis dengan tanda kutip yang benar dan dipilih secara sadar di antara dua gaya penyaringan yang tersedia.
Sintaks dasar query#
query menerima string yang memuat ekspresi logika, dan nama kolom ditulis langsung tanpa tanda kutip maupun tanda $, sedangkan nilai teks di dalam ekspresi tetap membutuhkan tanda kutip sendiri. Konjungsi and, or, dan not sah di dalam string ekspresi, berbeda dengan indeks boolean yang mewajibkan &, |, dan ~. Dataset modul ini kembali dibangun oleh generator deterministik yang sama.
import numpy as np
import pandas as pd
rng = np.random.default_rng(42)
n = 96
df = pd.DataFrame({
"waktu": pd.date_range("2026-01-05 07:00", periods=n, freq="15min"),
"ruang": rng.choice(["Lab A", "Lab B", "Ruang Arsip"], n, p=[0.4, 0.35, 0.25]),
"suhu_c": np.round(rng.normal(24, 1.5, n), 1),
"lembap_pct": np.round(rng.normal(60, 5, n), 1),
"status_sensor": rng.choice(["normal", "kalibrasi", "rusak"], n, p=[0.85, 0.10, 0.05]),
})
df.to_csv("sensor_log.csv", index=False) # disimpan agar blok berikutnya cukup membaca berkas ini
print(df.shape)(96, 5)Blok berikut menyaring bacaan panas pada Lab A. Baris pd.options.compute.use_numexpr = False menonaktifkan akselerasi numexpr dan ditulis pada setiap contoh query karena lingkungan contoh memasang numexpr yang lebih tua daripada versi minimum yang didukung pandas 3.1, sehingga tanpa baris itu pandas menampilkan peringatan versi pada setiap proses baru. Pada instalasi biasa dengan numexpr terkini, baris tersebut tidak diperlukan.
import pandas as pd
pd.options.compute.use_numexpr = False # numexpr lingkungan contoh lebih tua dari minimum pandas 3.1
df = pd.read_csv("sensor_log.csv", parse_dates=["waktu"])
panas_lab_a = df.query("suhu_c > 25 and ruang == 'Lab A'")
print(panas_lab_a[["waktu", "ruang", "suhu_c"]]) waktu ruang suhu_c
32 2026-01-05 15:00:00 Lab A 26.2
43 2026-01-05 17:45:00 Lab A 25.3
68 2026-01-06 00:00:00 Lab A 27.2
70 2026-01-06 00:30:00 Lab A 25.3Empat baris memenuhi kedua syarat sekaligus, dan perhatikan penandaan kutipnya, yaitu kutip ganda untuk string python dan kutip tunggal untuk nilai 'Lab A' di dalamnya. Nilai angka ditulis apa adanya, sedangkan nama kolom seperti suhu_c dikenali dari kolom tabel tanpa deklarasi apa pun.
Di dalam satu string ekspresi, kolom juga dapat dihitung dan dibandingkan langsung dengan kolom lain, misalnya lembap_pct - suhu_c > 35 untuk selisih kelembapan terhadap suhu, atau suhu_c < lembap_pct untuk perbandingan dua kolom tanpa konstanta apa pun. Kemampuan ini memperluas penyaringan dari sekadar ambang tetap menjadi hubungan antar kolom, dan semuanya tetap ditulis dalam satu baris string yang sama.
Variabel python dengan @nama#
Nilai yang sudah tersimpan pada variabel python dapat dipakai di dalam string ekspresi lewat tanda @ di depan namanya. Tanpa @, nama itu dicari sebagai kolom atau variabel di dalam lingkungan ekspresi, bukan di lingkungan program, dan pencarian itu berakhir error. Bentuk @ menjaga ambang batas tetap satu sumber kebenaran, misalnya ambang suhu yang ditetapkan sekali di bagian atas skrip.
import pandas as pd
pd.options.compute.use_numexpr = False # numexpr lingkungan contoh lebih tua dari minimum pandas 3.1
df = pd.read_csv("sensor_log.csv", parse_dates=["waktu"])
batas = 25
panas = df.query("suhu_c > @batas")
print("query @batas :", len(panas))
print("indeks boolean:", len(df.loc[df["suhu_c"] > batas]))query @batas : 21
indeks boolean: 21Kedua gaya menghasilkan 21 baris yang sama persis karena ekspresinya setara. Variabel yang dirujuk tanpa @ berakhir UndefinedVariableError, dan bentuk error itu diperlihatkan pada bagian Kesalahan umum.
Memilih antara query dan indeks boolean#
query dan indeks boolean menghasilkan baris yang identik untuk ekspresi yang setara, sehingga pilihannya adalah soal keterbacaan dan bentuk kondisi yang tersedia. query unggul bila kondisinya banyak dan bertuliskan perbandingan antar kolom, karena string ekspresinya pendek tanpa tanda kurung per kondisi. Indeks boolean lebih tepat bila mask perlu dipakai ulang, dihitung, atau dibentuk dari hasil metode seperti isin, between, dan aksesor .str, karena mask adalah Series biasa yang dapat disimpan dan digabung di luar pemanggilan seleksi.
import pandas as pd
pd.options.compute.use_numexpr = False # numexpr lingkungan contoh lebih tua dari minimum pandas 3.1
df = pd.read_csv("sensor_log.csv", parse_dates=["waktu"])
lewat_query = df.query("suhu_c < 22 or suhu_c > 26")
lewat_mask = df.loc[(df["suhu_c"] < 22) | (df["suhu_c"] > 26)]
print(len(lewat_query), len(lewat_mask))
print(lewat_query.equals(lewat_mask))18 18
TrueDelapan belas baris berada di luar rentang 22 sampai 26 derajat menurut kedua gaya, dan metode equals() menyatakan keduanya identik termasuk urutan barisnya. Hasil yang sama ini bukan kebetulan, karena query pada akhirnya mengevaluasi ekspresi menjadi mask boolean yang sama, dengan mesin ekspresi pandas dan pustaka numexpr menangani perhitungannya bila pustaka itu tersedia dan versinya didukung.
Satu perbedaan praktis perlu diingat, yaitu string ekspresi tidak diperiksa linter python karena bukan kode python, sehingga kesalahan nama kolom baru terasa saat eksekusi, sedangkan mask boolean ditulis dengan nama kolom python biasa yang diperiksa editor. Karena itu, query paling menguntungkan pada tahap eksplorasi, ketika banyak kondisi teks perlu dicoba dan diubah-ubah. Indeks boolean lebih tepat pada skrip yang stabil, tempat mask dipakai ulang untuk beberapa seleksi, dihitung jumlah True-nya, atau dibentuk dari hasil metode seperti isin, between, dan aksesor .str yang tidak punya padanan di dalam string ekspresi.
Kesalahan umum#
Kesalahan pertama adalah merujuk variabel python tanpa @, yang dicari sebagai variabel ekspresi dan berakhir UndefinedVariableError. Kesalahan kedua adalah menulis nilai teks tanpa tanda kutip, sehingga parser ekspresi menolaknya dengan SyntaxError. Keduanya diperlihatkan berdampingan.
import pandas as pd
pd.options.compute.use_numexpr = False # numexpr lingkungan contoh lebih tua dari minimum pandas 3.1
df = pd.read_csv("sensor_log.csv", parse_dates=["waktu"])
batas = 25
try:
df.query("suhu_c > batas")
except Exception as e:
print(type(e).__name__, str(e))
try:
df.query("ruang == Lab A")
except Exception as e:
print(type(e).__name__, str(e))UndefinedVariableError name 'batas' is not defined
SyntaxError invalid syntax (<unknown>, line 1)Perbaikan untuk keduanya sudah tampak pada contoh yang benar, yaitu @batas dan 'Lab A'. Kesalahan ketiga adalah memakai tanda kutip yang sama untuk string python dan nilai di dalamnya, misalnya "ruang == "Lab A"", yang memutus string python lebih dahulu dan berakhir error sintaks pada baris itu sendiri. Pilih tanda kutip luar dan dalam yang berbeda. Kesalahan keempat adalah menulis query pada kolom yang namanya mengandung spasi, karena parser membaca nama tersebut sebagai dua istilah. Nama seperti itu harus dibungkus backtick di dalam string ekspresi.
import pandas as pd
pd.options.compute.use_numexpr = False # numexpr lingkungan contoh lebih tua dari minimum pandas 3.1
df = pd.read_csv("sensor_log.csv", parse_dates=["waktu"])
df_sp = df.rename(columns={"suhu_c": "suhu celcius"})
print(len(df_sp.query("`suhu celcius` > 26")))9Sembilan baris memiliki suhu di atas 26 derajat menurut kolom yang kini bernama suhu celcius. Larangannya berlaku dua arah, yaitu nama kolom tanpa spasi tidak perlu backtick dan penambahan spasi pada nama kolom sebaiknya dihindari sejak awal agar query maupun akses kolom tetap ringkas.
Ringkasan#
df.query("ekspresi")mengekspresikan kondisi baris sebagai string, denganand,or, dannotsah di dalamnya.- Variabel python dirujuk dengan tanda
@, sedangkan nama tanpa@dicari di lingkungan ekspresi dan berakhirUndefinedVariableError. - Nilai teks di dalam ekspresi membutuhkan tanda kutip yang berbeda dari kutip string luarnya, dan kolom bernama spasi dibungkus backtick.
querymenang pada gabungan kondisi yang panjang, sedangkan indeks boolean lebih tepat bila mask dipakai ulang atau dibentuk dari hasil metode.
Referensi#
- pandas.DataFrame.query — pandas API reference — dokumentasi resmi query beserta aturan ekspresi, tanda @, dan backtick.
- Indexing and selecting data — pandas User Guide — bab resmi yang memuat bagian The query() Method dan batasannya.