Pertanyaan analisis hampir selalu berbicara per kelompok, misalnya rata-rata
per stasiun atau maksimum per jam, dan groupby adalah jawaban pandas untuk
semuanya. Topik ini membedah pola split-apply-combine yang melandasinya,
menerapkannya dengan beberapa agregat sekaligus, serta memperkenalkan
transform yang mengembalikan hasil ke bentuk baris aslinya. Setelah
membacanya, ringkasan per kelompok pada seluruh modul EDA berikutnya sudah
dikuasai pola kerjanya.
Split, apply, combine#
groupby memecah tabel menjadi kelompok menurut nilai satu atau beberapa
kolom, menerapkan satu fungsi pada setiap kelompok, lalu menggabungkan hasilnya
menjadi tabel baru. Tiga langkah itu dijuluki split-apply-combine, dan
memahaminya membuat seluruh variasi groupby dapat ditebak daripada
dihafalkan.
Skrip berikut menerapkan pola itu pada data pengukuran dua stasiun, dengan
tiga agregat sekaligus, penentuan jam dengan nilai tertinggi, dan
transform yang menempelkan rata-rata kelompok ke setiap baris.
"""Agregasi per kelompok dengan groupby."""
import pandas as pd
data = pd.DataFrame(
{
"stasiun": ["A", "A", "A", "B", "B", "B"],
"jam": [8, 9, 10, 8, 9, 10],
"pm25": [34.0, 41.5, 28.0, 52.3, 47.0, 61.2],
}
)
ringkas = data.groupby("stasiun")["pm25"].agg(["count", "mean", "max"])
print(ringkas.round(1).to_string())
per_jam = data.groupby("jam")["pm25"].mean()
print(per_jam.idxmax(), per_jam.max().round(1))
print(data.groupby("stasiun")["pm25"].transform("mean").round(1).tolist()) count mean max
stasiun
A 3 34.5 41.5
B 3 53.5 61.2
10 44.6
[34.5, 34.5, 34.5, 53.5, 53.5, 53.5]Baris pertama keluaran memperlihatkan hasil combine, yaitu tabel baru yang
indeksnya nilai kelompok dan kolomnya agregat yang diminta. Stasiun B
konsisten lebih tinggi daripada A pada data kecil ini, dan count yang
tampil bersamanya memberi bobot jumlah data, yaitu kebiasaan yang penting
karena rata-rata tanpa jumlah data mudah meleset maknanya.
Banyak agregat dan banyak kunci#
.agg() menerima satu daftar fungsi, kamus yang memetakan kolom ke agregatnya
masing-masing, atau fungsi buatan sendiri. Bentuk kamusnya yang paling sering
berguna pada praktik, misalnya
data.groupby("stasiun").agg(pm25_rata=("pm25", "mean"), suhu_max=("suhu_c", "max")),
yang sekaligus menamai kolom hasilnya dengan jelas.
Kunci kelompok dapat lebih dari satu dengan menyebutkan daftar kolom, dan
hasilnya bertingkat, misalnya groupby(["stasiun", "jam"]) memberi satu
baris untuk setiap pasangan stasiun dan jam. Tabel bertingkat ini
diperdalam pada modul segmentasi karena menjadi alat utamanya, dan
reset_index() mengembalikannya menjadi tabel datar yang lebih mudah
digabungkan dengan data lain.
Agregat yang dipilih harus dibaca ulang sebelum dilaporkan. sum pada data
pengukuran per jam bermakna akumulasi, sedangkan mean menyatakan tingkat
rata-rata, dan keduanya sah tetapi menjawab pertanyaan yang berbeda. Kebiasaan
menyebut satuannya pada nama kolom hasil, misalnya pm25_rata, menjaga
pembacaan tetap jujur.
Transform untuk kembali ke baris#
Agregasi menyusutkan setiap kelompok menjadi satu baris, sedangkan
transform menerapkan perhitungan kelompok yang sama tetapi mengembalikan
hasil dengan panjang yang sama seperti tabel aslinya. Baris ketiga keluaran di
atas memperlihatkannya, yaitu setiap baris stasiun A membawa 34.5 dan setiap
baris B membawa 53.5.
Bentuk inilah yang dibutuhkan ketika nilai kelompok perlu dibandingkan dengan
barisnya sendiri, misalnya selisih setiap pengukuran terhadap rata-rata
stasiunnya atau penyusutan dari terbesar kelompoknya. Pola umumnya adalah
data["pm25"] - data.groupby("stasiun")["pm25"].transform("mean"), dan
hasilnya adalah penyimpangan yang terstandardisasi per kelompok tanpa
perulangan apa pun.
Pasangan lain yang sering muncul adalah filter, yang mengembalikan seluruh
baris kelompok yang lolos syarat tingkat kelompok, misalnya kelompok dengan
jumlah data lebih dari dua. Ketiganya membentuk satu keluarga, yaitu apply
untuk fleksibilitas penuh, transform untuk membentuk ulang ke baris, dan
filter untuk memilih kelompok.
Kesalahan umum#
Kesalahan pertama adalah membaca hasil groupby sebagai tabel biasa tanpa
menyadari indeksnya adalah kunci kelompok. Operasi yang mengandalkan nomor
posisi kemudian meleset, sedangkan reset_index() atau argumen
as_index=False mengembalikan bentuk tabel yang akrab.
Kesalahan kedua adalah rata-rata rata-rata, yaitu mengagregasi hasil agregasi
tanpa menimbang ukuran kelompok. Rata-rata dari 34.5 dan 53.5 memang 44.0,
dan kebetulan rata-rata keseluruhan enam baris data ini juga 44.0, tetapi
kebetulan itu menyesatkan: pada ukuran kelompok yang timpang, rata-rata
rata-rata berbeda nyata dari rata-rata keseluruhan. Bobot
dihitung dari count, bukan diabaikan.
Kesalahan ketiga adalah lupa nilai hilang. Secara bawaan groupby
melewati kunci yang NaN sehingga baris tersebut keluar dari semua kelompok,
dan jumlah baris hasil agregasi yang kurang dari tabel aslinya adalah
sinyalnya. Perlakuan atas data hilang diambil sebelumnya, sebagaimana dibahas
pada modul pembersihan.
Ringkasan#
groupbybekerja dengan pola split-apply-combine, dan indeks hasilnya adalah kunci kelompok..agg()menerima banyak agregat sekaligus dan menamai kolom hasilnya, sedangkan kunci kelompok ganda menghasilkan tabel bertingkat.transformmengembalikan perhitungan kelompok ke panjang baris asli, sehingga setiap baris dapat dibandingkan dengan kelompoknya.- Rata-rata antar kelompok harus ditimbang ukuran kelompoknya, dan kunci
NaNdilewati secara bawaan.
Referensi#
- Group by: split-apply-combine — pandas documentation
—
dokumentasi resmi
groupby,agg,transform, danfilter. - pandas API reference: DataFrame.groupby
—
rujukan parameter lengkap termasuk
as_indexdandropna.