Filter, Sort, dan GroupBy
Boolean indexing, sort_values, groupby + agg: tiga jurus menjawab pertanyaan bisnis dari data.
Tiga jurus menjawab pertanyaan bisnis
Analogi: kalau DataFrame itu gudang berisi ribuan kardus, maka filter adalah petugas yang hanya mengambil kardus berlabel tertentu, sort menyusunnya dari terbesar ke terkecil, dan groupby adalah kasir yang mengelompokkan struk per kategori lalu menjumlahkan totalnya. Tiga jurus ini menjawab 80% pertanyaan bisnis sehari-hari: "produk apa yang paling laku?", "kota mana omzetnya terbesar?", "rata-rata belanja per pelanggan berapa?".
Contoh pertama, filter dan urutkan. Pola intinya adalah boolean indexing: kondisi menghasilkan Series True/False yang dipakai sebagai masker.
mahal = df[df["harga"] > 10000]
laris_mahal = df[(df["harga"] > 10000) & (df["jumlah"] >= 5)]
top = df.sort_values("omzet", ascending=False).head(3)Tiap kondisi wajib dibungkus kurung, dan penghubungnya & (dan) atau | (atau), bukan kata and/or. Alasannya ada di jebakan di bawah.
Contoh kedua, studi kasus realistis: rekap penjualan per produk dari dataset kecil.
import pandas as pd
df = pd.DataFrame({
"produk": ["Kopi", "Teh", "Kopi", "Susu", "Teh", "Kopi"],
"jumlah": [10, 7, 5, 12, 9, 8],
"harga": [15000, 8000, 15000, 12000, 8000, 15000],
})
df["omzet"] = df["jumlah"] * df["harga"]
rekap = (
df.groupby("produk")
.agg(total_terjual=("jumlah", "sum"),
rata_harga=("harga", "mean"),
total_omzet=("omzet", "sum"))
.sort_values("total_omzet", ascending=False)
.reset_index()
)
print(rekap)Pola split-apply-combine: data dipecah per produk, tiap kelompok dihitung total dan rata-ratanya, hasilnya digabung jadi tabel rekap. Sintaks total_terjual=("jumlah", "sum") (named aggregation) membuat nama kolom hasilnya rapi dan deskriptif. Di SQL ini padanannya GROUP BY, konsepnya sama persis, jadi skill ini terbawa ke modul SQL nanti.
Jebakan umum
SALAH: pakai and untuk menggabungkan kondisi filter.
df[(df["harga"] > 10000) and (df["jumlah"] >= 5)]
# ValueError: The truth value of a Series is ambiguousBENAR: pakai & (dan | untuk atau).
df[(df["harga"] > 10000) & (df["jumlah"] >= 5)]Penjelasannya: and hanya mengerti satu nilai True/False, sedangkan kondisi pandas menghasilkan ratusan True/False sekaligus. Operator & bekerja elemen-per-elemen, itulah yang dibutuhkan.
SALAH: ubah nilai pakai chained indexing (kurung siku beruntun).
df[df["produk"] == "Kopi"]["harga"] = 16000 # diam-diam gagal / warningBENAR: pakai .loc dengan masker dalam satu langkah.
mask = df["produk"] == "Kopi"
df.loc[mask, "harga"] = 16000 # pasti kena baris yang tepatPola beruntun df[...][...] kadang mengubah salinan sementara, bukan data aslinya, sehingga muncul SettingWithCopyWarning yang terkenal itu. Aturannya simpel: baca boleh beruntun, tapi kalau mengubah data selalu lewat .loc.
Catatan teknis: Hasil
groupbymenjadikan kolom grup sebagai index. Tambahkan.reset_index()di akhir supaya ia kembali jadi kolom biasa, karena kebanyakan operasi lanjutan (merge, plot, export CSV) lebih nyaman dengan kolom biasa.
Tantangan
Top 3 produk terlaris
Dari DataFrame penjualan (kolom produk, jumlah, harga): tambah kolom omzet, filter hanya produk dengan omzet > 50000, urutkan menurun, dan ambil 3 teratas dengan .head(3).
Kuis Bab
Uji pemahamanmu: Bab 5: NumPy dan pandas Dasar
Jawab 5 soal berikut, lalu tekan "Periksa Jawaban".
1.Apa shape dari np.array([[1, 2, 3], [4, 5, 6]])?
2.Apa hasil dari np.array([1, 2, 3]) + 10?
3.Apa yang dikembalikan df['nama'] pada sebuah DataFrame?
4.Apa yang dilakukan df[df['umur'] > 30]?
5.Untuk apa df.groupby('kota')['gaji'].mean() dipakai?