Agregasi ganda menerapkan fungsi yang berbeda pada kolom yang berbeda dalam satu panggilan agg, dan hasilnya berupa tabel dengan kolom bertingkat berlabel MultiIndex. Topik ini membahas bentuk dict pada agg, cara membaca dan memilih kolom hasil bertingkat, serta cara meratakan namanya agar tabel ringkasan tetap mudah dipakai. Setelah membaca, ringkasan statistik lengkap per ruangan dapat dibentuk dan ditangani tanpa tersandung struktur kolomnya.
Satu panggilan agg dengan dict#
Bentuk dict pada agg memetakan nama kolom ke fungsi yang diinginkan, sehingga setiap kolom diperlakukan sesuai kebutuhannya dalam satu panggilan. Nilai dict boleh berupa satu nama fungsi untuk kolom tunggal atau daftar nama fungsi untuk beberapa statistik sekaligus. Kolom yang tidak disebut pada dict tidak ikut dihitung, sehingga tabel hasil hanya memuat yang diminta.
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"])
ringkasan = df.groupby("ruang").agg({"suhu_c": ["min", "mean", "max"], "lembap_pct": "mean"})
print(ringkasan)
print("kolom hasil:", list(ringkasan.columns)) suhu_c lembap_pct
min mean max mean
ruang
Lab A 21.4 23.730556 27.2 60.605556
Lab B 20.8 23.807895 26.7 59.557895
Ruang Arsip 21.5 24.259091 28.4 59.177273
kolom hasil: [('suhu_c', 'min'), ('suhu_c', 'mean'), ('suhu_c', 'max'), ('lembap_pct', 'mean')]Tabel hasil memuat empat kolom statistik dari dua kolom asal, dan tampilannya bertingkat karena satu kolom asal dapat menghasilkan lebih dari satu fungsi. Deretan list(ringkasan.columns) memperlihatkan struktur aslinya, yaitu pasangan seperti ('suhu_c', 'mean') yang berisi nama kolom asal pada level luar dan nama fungsi pada level dalam. Kolom waktu dan status_sensor tidak muncul karena tidak disebut pada dict. Struktur bertingkat inilah yang dibaca dan diratakan pada bagian berikutnya.
Membaca dan memilih kolom MultiIndex#
MultiIndex adalah index bertingkat yang setiap kolomnya dikenali oleh satu pasangan label, yaitu level luar berupa nama kolom asal dan level dalam berupa nama fungsi. Memilih satu kolom hasil dilakukan dengan tuple seperti ringkasan[("suhu_c", "mean")], sedangkan memilih level luar seperti ringkasan["suhu_c"] mengembalikan sub-tabel berisi seluruh fungsi kolom tersebut. Dua bentuk seleksi ini mencakup hampir seluruh kebutuhan pembacaan hasil.
import pandas as pd
df = pd.read_csv("sensor_log.csv", parse_dates=["waktu"])
ringkasan = df.groupby("ruang").agg({"suhu_c": ["min", "mean", "max"], "lembap_pct": "mean"})
print(ringkasan[("suhu_c", "mean")])
print(ringkasan["suhu_c"])ruang
Lab A 23.730556
Lab B 23.807895
Ruang Arsip 24.259091
Name: (suhu_c, mean), dtype: float64
min mean max
ruang
Lab A 21.4 23.730556 27.2
Lab B 20.8 23.807895 26.7
Ruang Arsip 21.5 24.259091 28.4Panggilan pertama menghasilkan Series bernama (suhu_c, mean) berisi rata-rata suhu per ruang, sedangkan panggilan kedua menghasilkan tabel tiga kolom berisi minimum, rata-rata, dan maksimum suhu. Penentu pilihannya adalah tingkat kedalaman yang diinginkan, yaitu satu angka dengan tuple dan satu kelompok fungsi dengan label level luar. Seleksi bertingkat ini bekerja hanya ketika bentuk pemilihnya lengkap, sebagaimana ditunjukkan pada bagian Kesalahan umum.
Meratakan nama kolom hasil#
Nama kolom bertingkat dapat diratakan menjadi satu level dengan menggabungkan pasangannya, misalnya ("suhu_c", "mean") menjadi suhu_c_mean. Cara paling langsung adalah menetapkan ulang ringkasan.columns dengan daftar hasil penggabungan, dan penugasan atribut semacam ini sah dilakukan pada tabel hasil agregasi. Nama yang rata membuat chaining tetap mudah karena pemilihan kolom berikutnya cukup menyebut satu nama sederhana.
import pandas as pd
df = pd.read_csv("sensor_log.csv", parse_dates=["waktu"])
ringkasan = df.groupby("ruang").agg({"suhu_c": ["min", "mean", "max"], "lembap_pct": "mean"})
ringkasan.columns = ["_".join(kolom) for kolom in ringkasan.columns]
print(ringkasan) suhu_c_min suhu_c_mean suhu_c_max lembap_pct_mean
ruang
Lab A 21.4 23.730556 27.2 60.605556
Lab B 20.8 23.807895 26.7 59.557895
Ruang Arsip 21.5 24.259091 28.4 59.177273Kolom hasil kini bernama suhu_c_min, suhu_c_mean, suhu_c_max, dan lembap_pct_mean, sehingga setiap kolom dapat dipilih dengan satu nama tanpa tuple. Alternatif yang menghindarkan MultiIndex sejak awal adalah agregasi bernama dari topik Agregasi Dasar, yang menetapkan satu nama hasil untuk setiap pasangan kolom dan fungsi. Pilih rataan nama bila banyak fungsi per kolom memang diperlukan, dan pilih agregasi bernama bila jumlah kolom hasilnya sedikit.
Kesalahan umum#
Kesalahan paling lazim adalah memilih kolom hasil dengan nama fungsi saja, misalnya ringkasan["mean"], karena nama mean berada di level dalam MultiIndex dan tidak pernah menjadi nama kolom utuh. pandas menjawabnya dengan KeyError yang menyebut label persis seperti yang ditulis. Perbaikannya adalah memakai tuple dua level, memilih level luarnya terlebih dahulu, atau meratakan nama kolom seperti pada bagian sebelumnya.
import pandas as pd
df = pd.read_csv("sensor_log.csv", parse_dates=["waktu"])
ringkasan = df.groupby("ruang").agg({"suhu_c": ["min", "mean", "max"], "lembap_pct": "mean"})
try:
print(ringkasan["mean"])
except KeyError as e:
print("KeyError:", e)KeyError: 'mean'Pesan KeyError: 'mean' muncul karena tidak ada kolom bernama mean pada level luar, dan bukan karena fungsi mean tidak pernah dihitung. Kebiasaan yang mencegah kesalahan ini adalah memeriksa ringkasan.columns setelah agregasi ganda, sebagaimana dicontohkan pada bagian pertama, sehingga bentuk kolom yang ada selalu diketahui sebelum dipilih.
Ringkasan#
agg({"suhu_c": ["min", "mean", "max"], "lembap_pct": "mean"})menerapkan fungsi berbeda per kolom dalam satu panggilan.- Hasilnya memakai MultiIndex dua level, yaitu kolom asal di level luar dan nama fungsi di level dalam.
- Satu kolom hasil dipilih dengan tuple seperti
("suhu_c", "mean"), dan satu kelompok fungsi dipilih dengan label level luarnya. ringkasan.columns = ["_".join(kolom) for kolom in ringkasan.columns]meratakan nama kolom, sedangkan nama level dalam seperti"mean"sendirian memicuKeyError.
Referensi#
- pandas.core.groupby.DataFrameGroupBy.aggregate — pandas API reference — dokumentasi resmi bentuk dict, list, dan agregasi bernama pada agg.
- Group by: split-apply-combine — pandas User Guide — bab resmi pengelompokan beserta perilaku hasil agregasinya.