pythonpandasgroupbyMenengah4 mnt baca

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.

python
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.

python
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.

python
df[(df["harga"] > 10000) and (df["jumlah"] >= 5)]
# ValueError: The truth value of a Series is ambiguous

BENAR: pakai & (dan | untuk atau).

python
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).

python
df[df["produk"] == "Kopi"]["harga"] = 16000   # diam-diam gagal / warning

BENAR: pakai .loc dengan masker dalam satu langkah.

python
mask = df["produk"] == "Kopi"
df.loc[mask, "harga"] = 16000   # pasti kena baris yang tepat

Pola 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 groupby menjadikan 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?