Pertanyaan analisis tentang kelompok datang dalam dua rupa. Ada yang menuntut ringkasan, misalnya rata-rata skor setiap kelompok belajar; ada pula yang menuntut pelabelan per baris, misalnya selisih setiap skor terhadap rata-rata kelompoknya. pandas menjawab keduanya lewat groupby dengan dua method yang sering tertukar: agg() yang meringkas dan transform() yang mempertahankan bentuk. Chapter ini membandingkan keduanya pada satu dataset yang sama, sehingga perbedaan bentuk hasilnya terlihat nyata; rujukan lengkapnya ada di Group by: split-apply-combine
.
Satu Dataset, Dua Pendekatan #
Contoh berikut memakai DataFrame nilai berisi lima peserta dari dua kelompok. Kita menghitung rata-rata skor per kelompok dengan dua cara sekaligus: sekali melalui agg(), sekali melalui transform(), lalu memakai hasil transform() untuk membuat kolom selisih.
import pandas as pd
nilai = pd.DataFrame(
{
"kelompok": ["A", "A", "B", "B", "B"],
"nama": ["Budi", "Siti", "Dewi", "Andi", "Rina"],
"skor": [80, 90, 75, 65, 85],
}
)
rata_kelompok = nilai.groupby("kelompok")["skor"].agg("mean")
print(rata_kelompok)
print()
rata_baris = nilai.groupby("kelompok")["skor"].transform("mean")
print(rata_baris)
print()
selisih = nilai["skor"] - rata_baris
lengkap = nilai.assign(selisih_dari_rata=selisih)
print(lengkap)Output yang Dihasilkan:
kelompok
A 85.0
B 75.0
Name: skor, dtype: float64
0 85.0
1 85.0
2 75.0
3 75.0
4 75.0
Name: skor, dtype: float64
kelompok nama skor selisih_dari_rata
0 A Budi 80 -5.0
1 A Siti 90 5.0
2 B Dewi 75 0.0
3 B Andi 65 -10.0
4 B Rina 85 10.0Mari kita telaah apa yang terjadi pada kode di atas:
- Baris 3-9: membangun DataFrame
nilaidengan lima baris; kolomkelompokmenjadi kunci pengelompokan. - Baris 11:
agg("mean")menghitung satu rata-rata untuk setiap kelompok, sehingga lima baris meringkas menjadi dua nilai. - Baris 16:
transform("mean")menghitung rata-rata kelompok yang sama, tetapi hasilnya disiarkan (broadcast) kembali ke setiap baris anggota kelompoknya. - Baris 21-22: kolom
skordikurangirata_barisper baris, laluassign()menambahkan hasilnya sebagai kolomselisih_dari_rata. - Baris 24: perintah
printmenampilkan DataFramelengkapyang bergabung kembali dengan selisihnya.
aggregate(): Satu Nilai per Kelompok #
Blok output pertama adalah wujud agg(): Series baru dengan dua baris, index-nya berupa label kelompok A dan B, dan name-nya masih skor. Bentuk data menyusut dari lima baris menjadi dua baris karena seluruh anggota kelompok dilebur menjadi satu angka. Bentuk inilah yang kita inginkan untuk laporan ringkasan, misalnya tabel rekap yang akan ditampilkan ke manajemen. Method agg() tidak terbatas pada "mean"; kita dapat mengirim "sum", "max", daftar seperti ["mean", "max"], atau fungsi kustom, dengan rincian di dokumentasi pandas.DataFrame.agg
.
transform(): Rata-rata yang Membawa Index Baris #
Blok output kedua adalah wujud transform(): Series baru dengan lima baris, index-nya 0 sampai 4, persis sejajar dengan baris DataFrame asli. Setiap peserta menerima nilai rata-rata kelompoknya sendiri; Budi dan Siti sama-sama melihat 85.0, sedangkan Dewi, Andi, dan Rina melihat 75.0. Perataan (alignment) inilah yang membuat nilai["skor"] - rata_baris bisa dihitung tanpa loop: pandas mencocokkan kedua Series berdasarkan index baris. Hasil transform() memang dirancang untuk ditempel kembali ke data asli, berbeda dari hasil agg().
| Aspek | agg("mean") | transform("mean") |
|---|---|---|
| Bentuk hasil | Satu baris per kelompok | Sama dengan data asli |
| Index hasil | Label kelompok (A, B) | Index baris asli (0-4) |
| Pemakaian tipikal | Laporan ringkasan | Kolom tambahan per baris |
Kombinasi Keduanya dalam Satu Laporan #
Blok output ketiga memperlihatkan buah dari perataan itu: kolom selisih_dari_rata bernilai -5.0 untuk Budi karena skornya lima poin di bawah rata-rata kelompok A, dan 0.0 untuk Dewi karena skornya persis sama dengan rata-rata kelompok B. Pola “bandingkan setiap baris terhadap norma kelompoknya” sering muncul di analisis nyata, misalnya mendeteksi transaksi yang menyimpang dari rata-rata cabangnya. Dalam satu workflow, kita memakai agg() untuk tabel rekap dan transform() untuk pelabelan per baris, dan keduanya berasal dari panggilan groupby yang sama. Rincian parameter transform() ada di dokumentasi pandas.DataFrame.transform
.
transform() mengurus perhitungan sepanjang arah pengelompokan. Namun ketika logika transformasi menyentuh beberapa kolom dalam satu baris sekaligus, kita kembali ke apply() dengan axis=1 — bahasan penuh Chapter penutup Section ini.