pd.cut() menempatkan batas bin pada angka yang kita pilih, dan jumlah isi tiap bin bergantung pada sebaran data. Pada data yang condong (skewed), bin lebar sama bisa berisi sangat banyak baris di satu sisi dan nyaris kosong di sisi lain. pd.qcut() bekerja dari arah sebaliknya: batas bin dihitung dari kuantil data sehingga jumlah baris tiap bin cenderung sama. Pada Chapter ini kita mempraktikkan qcut() dengan label Indonesia, membaca tepi bin lewat retbins, lalu membandingkan hasilnya dengan cut() pada dataset yang sama.
Membagi Transaksi per Kuartil #
Kuartil membagi data terurut menjadi empat bagian sama besar: 25 persen baris terendah, 25 persen berikutnya, dan seterusnya. Skrip berikut memakai q=4 sehingga setiap transaksi mendapat salah satu dari empat label tingkat belanja. Jalankan skripnya, lalu bandingkan rekap kedua method di bagian akhir output.
import pandas as pd
pesanan = pd.DataFrame({
"id_pesanan": ["PSN-001", "PSN-002", "PSN-003", "PSN-004",
"PSN-005", "PSN-006", "PSN-007", "PSN-008"],
"nama_pelanggan": ["Budi", "Siti", "Dewi", "Andi",
"Rina", "Tono", "Lina", "Sari"],
"kota": ["Jakarta", "Bandung", "Surabaya", "Jakarta",
"Medan", "Bandung", "Jakarta", "Surabaya"],
"pembayaran": ["QRIS", "Transfer", "QRIS", "Kartu Kredit",
"COD", "Transfer", "QRIS", "COD"],
"nilai_transaksi": [250_000, 1_800_000, 750_000, 2_400_000,
480_000, 1_200_000, 320_000, 980_000],
"berat_paket": [1.2, 4.5, 0.8, 7.0, 2.5, 3.0, 1.0, 5.5],
})
nilai = pesanan["nilai_transaksi"]
pesanan["tingkat_belanja"] = pd.qcut(
nilai, q=4, labels=["Rendah", "Menengah", "Tinggi", "Sangat Tinggi"]
)
print(pesanan[["id_pesanan", "nilai_transaksi", "tingkat_belanja"]])
print()
print(pesanan["tingkat_belanja"].value_counts())
print()
tepi = pd.qcut(nilai, q=4, retbins=True)[1]
print(tepi)
print()
kelas = pd.cut(nilai, bins=[0, 500_000, 1_500_000, 2_500_000],
labels=["Murah", "Sedang", "Mahal"])
print(kelas.value_counts())Output yang Dihasilkan:
id_pesanan nilai_transaksi tingkat_belanja
0 PSN-001 250000 Rendah
1 PSN-002 1800000 Sangat Tinggi
2 PSN-003 750000 Menengah
3 PSN-004 2400000 Sangat Tinggi
4 PSN-005 480000 Menengah
5 PSN-006 1200000 Tinggi
6 PSN-007 320000 Rendah
7 PSN-008 980000 Tinggi
tingkat_belanja
Rendah 2
Menengah 2
Tinggi 2
Sangat Tinggi 2
Name: count, dtype: int64
[ 250000. 440000. 865000. 1350000. 2400000.]
nilai_transaksi
Murah 3
Sedang 3
Mahal 2
Name: count, dtype: int64Mari kita telaah apa yang terjadi pada kode di atas:
- Baris 17 (
nilai = pesanan["nilai_transaksi"]):qcut()menerima array-like apa pun; di sini kita memisahkan kolomnya dulu agar baris 27 bisa memanggilqcut()sekali lagi dengan data yang sama. - Baris 19-21 (
pesanan["tingkat_belanja"] = pd.qcut(...)): argumenq=4meminta empat bin berdasarkan kuartil, danlabels=[...]menamai kuartil pertama sampai keempat. Delapan transaksi terbagi rapi: tepat 2 baris per kelas, terlihat padavalue_counts()di baris 24. - Baris 27 (
pd.qcut(nilai, q=4, retbins=True)[1]): argumenretbins=Truemembuatqcut()mengembalikan tuple berisi hasil dan tepi binnya. Tepi yang tercetak adalah 250000, 440000, 865000, 1350000, dan 2400000: kuartil pertama (440.000) adalah titik interpolasi antara 320.000 dan 480.000, bukan angka bulat pilihan manusia. - Baris 31-33 (
kelas = pd.cut(...)): pada data yang sama,cut()dengan tepi manual menghasilkan 3-3-2. Kontras 2-2-2-2 versus 3-3-2 inilah perbedaan inti kedua method: qcut menjaga jumlah isi, cut menjaga lebar rentang.
Kapan Memilih cut(), Kapan qcut() #
| Aspek | pd.cut() | pd.qcut() |
|---|---|---|
| Batas bin | Ditentukan manual atau dibagi rata dari rentang | Dihitung dari kuantil data |
| Isi bin | Bergantung sebaran data | Cenderung sama banyak per bin |
| Makna kelas | Rentang bisnis tetap | Peringkat relatif dalam data |
| Contoh pakai | Kelas harga Murah-Sedang-Mahal | Kuartil belanja Rendah-Sangat Tinggi |
Pilih cut() bila kelas punya makna bisnis tetap: batas 500 ribu dan 1,5 juta tetap berlaku meskipun dataset berubah. Pilih qcut() bila yang penting peringkat relatif, misalnya 25 persen transaksi termurah masuk kelas Rendah apa pun nominalnya. Karena batas qcut() dihitung dari data, angkanya berubah ketika data berubah; simpan tepi bin dari retbins bila hasil harus konsisten antar batch. Referensi detail parameter tersedia di halaman pandas.qcut()
dan pandas.Series.quantile()
yang menjadi dasar perhitungannya.
Hasil qcut() sama seperti cut(): kolom bertipe category yang urutan kategorinya terurut. Keduanya bisa langsung dipakai untuk peringkasan atau digabungkan dengan kolom kategori lain. Untuk kebutuhan pemodelan, kategori sering perlu diubah lagi menjadi kolom biner, dan itu topik Chapter berikutnya: one-hot encoding dengan pd.get_dummies().