Pertanyaan analisis nyata jarang selesai dengan satu agregasi tunggal. Satu laporan penjualan biasanya menuntut ringkasan per kelompok, kontribusi persen per baris, penyaringan kelompok berdasarkan ambang, dan penandaan transaksi yang berbeda dari kelompoknya. Chapter ini menutup Section GroupBy dan Agregasi dengan satu studi kasus utuh: sepuluh transaksi toko yang dijawab dengan menggabungkan agg(), transform(), dan filter() dalam satu skrip. Setelah chapter ini, seluruh teknik kelompok siap kita bawa ke Section berikutnya.
Studi Kasus dan Empat Pertanyaan Analisis #
Kita memakai data transaksi tiga kategori (Elektronik, Pakaian, Makanan) di empat kota, lengkap dengan kuantitas dan harga satuan. Dari data ini, empat pertanyaan bisnis yang wajar diajukan manajer adalah:
- Bagaimana ringkasan total nilai, jumlah transaksi, dan rata-rata nilai per kota?
- Berapa persen kontribusi setiap transaksi terhadap total kotanya?
- Kota mana saja yang total nilainya mencapai minimal 5000?
- Transaksi mana saja yang nilainya di atas rata-rata kotanya?
Pertanyaan 1 dijawab dengan named aggregation, pertanyaan 2 dengan transform("sum") plus div(), pertanyaan 3 dengan filter(), dan pertanyaan 4 dengan perbandingan baris terhadap hasil transform("mean"). Satu skrip menjawab semuanya secara berurutan.
Dataset dan Kode Lengkap #
import pandas as pd
transaksi = pd.DataFrame({
"kota": ["Jakarta", "Jakarta", "Jakarta", "Bandung", "Bandung", "Bandung",
"Surabaya", "Surabaya", "Medan", "Medan"],
"kategori": ["Elektronik", "Pakaian", "Makanan", "Elektronik", "Pakaian", "Makanan",
"Elektronik", "Pakaian", "Elektronik", "Pakaian"],
"qty": [2, 5, 10, 1, 8, 4, 3, 4, 2, 3],
"harga_satuan": [1500, 400, 200, 2500, 250, 300, 1000, 500, 900, 200],
})
transaksi["nilai"] = transaksi["qty"] * transaksi["harga_satuan"]
print(transaksi, "\n")
print("1) Ringkasan per kota:")
ringkas = transaksi.groupby("kota").agg(
total=("nilai", "sum"),
jumlah_transaksi=("nilai", "size"),
rata_rata=("nilai", "mean"),
)
print(ringkas.round(1), "\n")
print("2) Kontribusi tiap transaksi terhadap total kotanya:")
total_kota = transaksi.groupby("kota")["nilai"].transform("sum")
transaksi["persen"] = transaksi["nilai"].div(total_kota).mul(100).round(1)
print(transaksi[["kota", "kategori", "nilai", "persen"]], "\n")
print("3) Kota dengan total nilai minimal 5000:")
utama = transaksi.groupby("kota").filter(lambda g: g["nilai"].sum() >= 5000)
print(utama[["kota", "kategori", "nilai"]], "\n")
print("4) Transaksi di atas rata-rata kotanya:")
rata_kota = transaksi.groupby("kota")["nilai"].transform("mean")
unggul = transaksi[transaksi["nilai"] > rata_kota]
print(unggul[["kota", "kategori", "nilai"]])Output yang Dihasilkan:
kota kategori qty harga_satuan nilai
0 Jakarta Elektronik 2 1500 3000
1 Jakarta Pakaian 5 400 2000
2 Jakarta Makanan 10 200 2000
3 Bandung Elektronik 1 2500 2500
4 Bandung Pakaian 8 250 2000
5 Bandung Makanan 4 300 1200
6 Surabaya Elektronik 3 1000 3000
7 Surabaya Pakaian 4 500 2000
8 Medan Elektronik 2 900 1800
9 Medan Pakaian 3 200 600
1) Ringkasan per kota:
total jumlah_transaksi rata_rata
kota
Bandung 5700 3 1900.0
Jakarta 7000 3 2333.3
Medan 2400 2 1200.0
Surabaya 5000 2 2500.0
2) Kontribusi tiap transaksi terhadap total kotanya:
kota kategori nilai persen
0 Jakarta Elektronik 3000 42.9
1 Jakarta Pakaian 2000 28.6
2 Jakarta Makanan 2000 28.6
3 Bandung Elektronik 2500 43.9
4 Bandung Pakaian 2000 35.1
5 Bandung Makanan 1200 21.1
6 Surabaya Elektronik 3000 60.0
7 Surabaya Pakaian 2000 40.0
8 Medan Elektronik 1800 75.0
9 Medan Pakaian 600 25.0
3) Kota dengan total nilai minimal 5000:
kota kategori nilai
0 Jakarta Elektronik 3000
1 Jakarta Pakaian 2000
2 Jakarta Makanan 2000
3 Bandung Elektronik 2500
4 Bandung Pakaian 2000
5 Bandung Makanan 1200
6 Surabaya Elektronik 3000
7 Surabaya Pakaian 2000
4) Transaksi di atas rata-rata kotanya:
kota kategori nilai
0 Jakarta Elektronik 3000
3 Bandung Elektronik 2500
4 Bandung Pakaian 2000
6 Surabaya Elektronik 3000
8 Medan Elektronik 1800Baris 3-10 membangun dataset sepuluh transaksi, lalu baris 11 menambahkan kolom nilai hasil perkalian qty * harga_satuan, sehingga setiap baris mewakili nilai uang satu transaksi. Empat bagian berikutnya saling berurutan dengan nomor 1 sampai 4 pada output. Mari kita baca hasil setiap bagian.
Ringkasan per Kota (Bagian 1) #
Named aggregation pada baris 15-19 menghasilkan tiga kolom sekaligus dalam satu panggilan agg(): total menjumlahkan nilai, jumlah_transaksi menghitung baris dengan "size", dan rata_rata menghitung mean. Output menunjukkan Jakarta sebagai kota dengan total tertinggi 7000 dari tiga transaksi, sedangkan Medan hanya 2400 dari dua transaksi. Bandingkan rata_rata Jakarta 2333.3 dengan Medan 1200.0: selisih ini yang nanti memengaruhi bagian 4.
Kontribusi Persen Tiap Transaksi (Bagian 2) #
Baris 23 menghasilkan total per kota di setiap baris dengan transform("sum"), lalu baris 24 membagi nilai transaksi dengan total tersebut dan mengalikan 100. Hasilnya bisa dibaca langsung: transaksi Elektronik Jakarta menyumbang 42.9 persen dari total kotanya, sedangkan di Medan satu transaksi Elektronik menyumbang 75.0 persen. Kolom persen seperti ini biasanya langsung dimasukkan ke dashboard karena menjawab “porsi apa” tanpa perlu pembaca berhitung.
Menyaring Kota Utama (Bagian 3) #
Baris 28 memakai groupby("kota").filter(lambda g: g["nilai"].sum() >= 5000). Medan dengan total 2400 dibuang utuh, sementara Surabaya yang tepat 5000 masih lolos karena kondisinya “minimal”. Output menyisakan delapan baris dari tiga kota dengan index asli 0 sampai 7. Perhatikan bahwa kondisi >= versus > benar-benar menentukan hasil di ambang batas, sehingga rumus ambang pada laporan harus dibaca dengan teliti.
Transaksi di Atas Rata-rata Kotanya (Bagian 4) #
Baris 31-32 menghitung rata-rata per kota pada setiap baris, lalu baris 33 membandingkannya dengan nilai transaksi menggunakan boolean mask. Lima transaksi lolos: Elektronik Jakarta 3000, Elektronik dan Pakaian Bandung (2500 dan 2000), Elektronik Surabaya 3000, serta Elektronik Medan 1800. Menariknya, semua transaksi yang berada di atas rata-rata kotanya berasal dari kategori Elektronik, sebuah temuan yang muncul justru karena kita membandingkan setiap transaksi dengan konteks kelompoknya, bukan dengan rata-rata keseluruhan data.
Pola Kerja Analisis Berbasis Kelompok #
Studi kasus ini memperlihatkan pola kerja yang bisa dipakai ulang untuk dataset apa pun. Pertama, pastikan kolom nilai siap (misalnya hasil perkalian kuantitas dan harga), lalu bangun ringkasan per kelompok dengan agg(). Selanjutnya bawa angka agregat kembali ke baris asli dengan transform() bila analisis membutuhkan perbandingan atau proporsi, dan gunakan filter() hanya saat kelompok utuh harus masuk atau keluar dari laporan.
Dokumentasi resmi untuk menuntaskan materi Section ini adalah panduan GroupBy , DataFrame.groupby , dan DataFrameGroupBy.agg .
Sampai di sini kita sudah mampu memecah data menjadi kelompok, merangkumnya, menyaringnya, dan menafsirkan proporsinya. Pertanyaan berikutnya biasanya bukan lagi tentang satu tabel, melainkan tentang menggabungkan beberapa tabel yang berbeda sumber; itulah topik Section Menggabungkan dan Membentuk Data.