Split-Apply-Combine

Mental model GroupBy sebagai proses split, apply, dan combine dengan diagram.

Daftar isi

Model GroupBy dalam pandas paling mudah dibaca sebagai proses tiga tahap bernama split-apply-combine, yaitu tabel dipecah per nilai kunci, satu fungsi diterapkan pada setiap pecahan, lalu hasilnya disatukan kembali menjadi satu tabel. Topik ini membahas ketiga tahap pada dataset log sensor suhu dan kelembapan tiga ruangan, mengenalkan objek yang dihasilkan df.groupby("ruang"), dan memetakan setiap tahap ke perintah SQL yang padanannya. Setelah membaca, setiap operasi groupby dapat diuraikan menjadi tiga tahap yang jelas sehingga sintaksnya terasa seperti penerapan model pikir, bukan mantra yang dihafal.

Tiga tahap split-apply-combine#

Model split-apply-combine menetapkan tiga tahap yang selalu berurutan pada setiap operasi groupby. Tahap split memecah tabel menjadi pecahan per nilai unik pada kolom kunci, misalnya satu pecahan untuk Lab A, satu pecahan untuk Lab B, dan satu pecahan untuk Ruang Arsip. Tahap apply menerapkan satu fungsi, seperti perhitungan rata-rata, pada setiap pecahan secara terpisah sehingga angka antar ruangan tidak saling tercampur. Tahap combine menyatukan hasil dari setiap pecahan menjadi satu tabel baru yang setiap barisnya mewakili satu grup.

Diagram berikut memperlihatkan ketiga tahap pada tabel log sensor yang dipecah berdasarkan kolom ruang. Tabel enam baris dipecah menjadi tiga pecahan berlabel ruangan, fungsi rata-rata menghasilkan satu angka per pecahan, dan tabel hasil berisi tiga baris ringkasan.

Model split-apply-combine pada log sensor1. split2. apply3. combinewakturuangsuhu_c07:00Ruang Arsip21.507:15Lab B21.807:30Ruang Arsip22.007:45Lab B22.508:00Lab A25.308:15Lab A22.6Lab A (36 baris)Lab B (38 baris)Ruang Arsip (22 baris)ruangrata suhu_cLab A23.73Lab B23.81Ruang Arsip24.26
Model split-apply-combine pada log sensor suhu tiga ruangan

Jumlah baris tabel hasil selalu sama dengan jumlah pecahan, yaitu jumlah nilai unik kunci grup, dan tidak lagi bergantung pada jumlah baris data asal. Sifat ini yang membuat hasil groupby layak disebut ringkasan, karena ukurannya menyusut dari sejumlah baris bacaan menjadi sejumlah grup. Kekeliruan memahami groupby umumnya berakar pada lupa bahwa apply bekerja satu pecahan demi satu pecahan, sehingga hasilnya memang dirancang per grup dan bukan per baris.

Memecah tabel dengan df.groupby(“ruang”)#

Pemanggilan df.groupby("ruang") menjalankan tahap split dan menghasilkan objek DataFrameGroupBy, yakni wadah berisi pecahan beserta rencana pengelompokannya. Objek ini belum menghitung apa pun sampai satu fungsi diterapkan, sehingga pembuatannya murah dan boleh dipakai berulang. Dua anggota kuncinya membantu memeriksa hasil split, yaitu groups yang berupa kamus kunci grup menuju label baris anggotanya dan size() yang menghitung jumlah baris per pecahan.

python Memecah log sensor per nilai kolom ruang
import numpy as np
import pandas as pd

rng = np.random.default_rng(42)
n = 96
df = pd.DataFrame({
    "waktu": pd.date_range("2026-01-05 07:00", periods=n, freq="15min"),
    "ruang": rng.choice(["Lab A", "Lab B", "Ruang Arsip"], n, p=[0.4, 0.35, 0.25]),
    "suhu_c": np.round(rng.normal(24, 1.5, n), 1),
    "lembap_pct": np.round(rng.normal(60, 5, n), 1),
    "status_sensor": rng.choice(["normal", "kalibrasi", "rusak"], n, p=[0.85, 0.10, 0.05]),
})
df.to_csv("sensor_log.csv", index=False)  # dataset bersama untuk seluruh modul
df = pd.read_csv("sensor_log.csv", parse_dates=["waktu"])
g = df.groupby("ruang")
print("jumlah pecahan:", g.ngroups)
print("kunci pecahan:", list(g.groups.keys()))
print(g.size())
text Keluaran
jumlah pecahan: 3
kunci pecahan: ['Lab A', 'Lab B', 'Ruang Arsip']
ruang
Lab A          36
Lab B          38
Ruang Arsip    22
dtype: int64

Keluaran memperlihatkan tiga fakta sekaligus. Jumlah pecahan adalah tiga sesuai tiga nilai unik kolom ruang, kunci pecahannya adalah Lab A, Lab B, dan Ruang Arsip, dan jumlah barisnya masing-masing 36, 38, serta 22. Jumlah ketiganya tepat 96, sama dengan panjang tabel asal, sehingga tidak ada baris yang hilang atau terpakai dua kali pada tahap split.

Menggabungkan pecahan dengan mean#

Tahap apply dan combine terlihat pada satu panggilan g.mean(numeric_only=True), yang menghitung rata-rata setiap kolom numerik pada setiap pecahan lalu menyatukan hasilnya menjadi satu tabel. Parameter numeric_only=True diperlukan karena tabel memuat kolom teks yang tidak mendukung perhitungan rata-rata. Hasilnya berupa tabel dengan kunci grup sebagai index baris, sehingga setiap baris mewakili satu ruangan.

python Rata-rata seluruh kolom numerik per pecahan
import pandas as pd

df = pd.read_csv("sensor_log.csv", parse_dates=["waktu"])
g = df.groupby("ruang")
print(g.mean(numeric_only=True))
text Keluaran
                suhu_c  lembap_pct
ruang
Lab A        23.730556   60.605556
Lab B        23.807895   59.557895
Ruang Arsip  24.259091   59.177273

Angka pada tabel hasil konsisten dengan ukuran pecahan pada bagian sebelumnya. Ruang Arsip mencatat rata-rata suhu tertinggi, yaitu 24.259091 derajat Celsius, meskipun jumlah bacaannya paling sedikit, sedangkan Lab A dan Lab B berada di kisaran 23.7 sampai 23.8 derajat. Kolom lembap_pct ikut dirata-rata karena bertipe numerik, sedangkan kolom waktu dan status_sensor tidak ikut karena bukan numerik. Perilaku ini menegaskan bahwa combine hanya menumpuk hasil per pecahan menjadi satu tabel, tanpa perhitungan lintas grup apa pun.

Padanan GROUP BY dalam SQL#

Setiap tahap groupby memiliki padanan langsung pada query SQL, dan pemetaan ini dinyatakan eksplisit agar pengetahuan SQL yang ada tetap terpakai. df.groupby("ruang") setara dengan klausa GROUP BY ruang, sedangkan fungsi yang diterapkan pada pecahan setara dengan fungsi agregat pada daftar SELECT, seperti AVG, COUNT, dan SUM. Tabel berikut merangkum padanannya.

pandasSQL
df.groupby("ruang")GROUP BY ruang
.mean()AVG(...)
.size()COUNT(*)
.agg(...)pemilihan fungsi agregat pada SELECT

Fragmen SQL berikut menghitung rata-rata dan maksimum suhu per ruang dari tabel sensor_log, dan strukturnya persis sama dengan panggilan df.groupby("ruang").agg(...) yang dibahas pada topik Agregasi Dasar.

sql Padanan GROUP BY pada log sensor
# tidak-dijalankan
SELECT ruang, AVG(suhu_c) AS suhu_rata, MAX(suhu_c) AS suhu_maks
FROM sensor_log
GROUP BY ruang;

Fragmen tersebut tidak dieksekusi di sini karena topik ini berisi Python, tetapi persamaannya mudah dilacak. Klausa AS suhu_rata pada SQL berperan seperti nama hasil pada agregasi bernama, FROM sensor_log seperti DataFrame sumber, dan GROUP BY ruang seperti pemanggilan groupby("ruang"). Dengan pemetaan ini, kebutuhan laporan yang dinyatakan dalam SQL dapat diterjemahkan menjadi panggilan groupby tanpa menghafal ulang dari nol.

Ringkasan#

  • df.groupby("ruang") menjalankan tahap split dan menghasilkan objek DataFrameGroupBy berisi pecahan per nilai unik kunci, tanpa menghitung apa pun sampai satu fungsi diterapkan.
  • g.groups dan g.size() mengungkap isi pecahan, yaitu label baris anggota dan jumlah baris untuk setiap kunci grup.
  • g.mean(numeric_only=True) menjalankan tahap apply per pecahan lalu menyatukan hasilnya menjadi satu tabel dengan kunci grup sebagai index.
  • Setiap operasi groupby setara dengan query SQL GROUP BY, dan fungsi per pecahannya setara dengan fungsi agregat seperti AVG, COUNT, dan SUM.

Referensi#