resample: Agregasi Waktu

Agregasi per hari dan per bulan dengan resample beserta ohlc untuk data harga.

Daftar isi

Dataset log sensor merekam bacaan setiap lima belas menit, sementara laporan biasanya meminta ringkasan per jam atau per hari, dan method resample menjembatani kebutuhan tersebut. Topik ini membahas agregasi waktu pada dataset kontrak, mulai dari rata-rata per jam, ringkasan per hari dengan beberapa fungsi sekaligus, hingga empat statistik per periode dengan ohlc. Setelah membaca, deret bacaan berfrekuensi tinggi dapat diringkas menjadi periode yang lebih panjang dengan label waktu yang terkontrol.

Membagi waktu menjadi kelompok per jam#

Method resample("h") membagi index waktu menjadi kelompok sepanjang satu jam, lalu fungsi agregasi seperti mean menghitung satu nilai untuk setiap kelompok. Method ini dipanggil pada kolom yang indexnya sudah bertipe datetime, sehingga set_index("waktu") mendahuluinya. Alias "h" menunjukkan satu jam, dan hasilnya berupa deret baru yang indexnya berisi label setiap kelompok.

python Rata-rata suhu per jam dengan resample
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"]).set_index("waktu")
per_jam = df["suhu_c"].resample("h").mean()
print(per_jam.head(6))
print("jumlah kelompok:", len(per_jam))
text Keluaran
waktu
2026-01-05 07:00:00    21.950
2026-01-05 08:00:00    24.125
2026-01-05 09:00:00    23.725
2026-01-05 10:00:00    23.200
2026-01-05 11:00:00    23.500
2026-01-05 12:00:00    23.900
Freq: h, Name: suhu_c, dtype: float64
jumlah kelompok: 24

Keluaran menunjukkan enam baris pertama dari 24 kelompok jam, yaitu rentang pukul 07.00 pada 5 Januari sampai 06.00 pada 6 Januari. Setiap kelompok memuat 4 bacaan lima belas menit, sehingga 96 bacaan terbagi rata ke dalam 24 kelompok dan rata-rata kelompok pertama sebesar 21.950 berasal dari bacaan 21.5, 21.8, 22.0, dan 22.5. Tanda Freq: h pada deret hasil menegaskan frekuensi kelompoknya satu jam. Perbandingan dengan groupby menegaskan karakter resample, karena groupby mengelompokkan baris menurut nilai kolom yang benar-benar ada, sedangkan resample menetapkan kelompoknya dari kalender waktu sehingga label hasilnya beraturan pukul 07.00, 08.00, dan seterusnya tanpa memedulikan isi bacaannya. Karakter inilah yang membuat resample tepat untuk deret berstempel waktu, sedangkan groupby tetap lebih cocok untuk pengelompokan menurut kategori seperti kolom ruang.

Resample per hari dengan beberapa fungsi#

Agregasi resample("D") membagi index waktu per hari kalender, dan .agg(["min", "mean", "max"]) menerapkan tiga fungsi sekaligus pada setiap kelompok. Alias "D" menunjukkan satu hari kalender, sehingga label hasilnya berupa tanggal tanpa komponen jam. Nama kolom hasil mengikuti nama fungsinya, sebagaimana perilaku agg pada groupby yang dibahas di topik Agregasi Dasar.

python Ringkasan suhu per hari dengan tiga fungsi
import pandas as pd

df = pd.read_csv("sensor_log.csv", parse_dates=["waktu"]).set_index("waktu")
per_hari = df["suhu_c"].resample("D").agg(["min", "mean", "max"])
print(per_hari)
text Keluaran
             min       mean   max
waktu
2026-01-05  20.8  23.727941  28.4
2026-01-06  21.9  24.257143  27.2

Tabel hasil hanya memuat dua baris karena lognya mencakup dua hari kalender, yaitu 68 bacaan pada 5 Januari dan 28 bacaan pada 6 Januari yang berhenti pukul 06.45. Rata-rata 6 Januari sebesar 24.257143 lebih tinggi daripada 5 Januari sebesar 23.727941, meskipun jumlah bacaannya lebih sedikit, sehingga ukuran kelompok dan isi statistiknya memang saling lepas. Kolom min, mean, dan max menyajikan sebaran harian dalam satu tabel ringkas yang siap ditulis ke laporan.

Empat nilai per periode dengan ohlc#

Method ohlc() pada hasil resample menghasilkan empat statistik per kelompok, yaitu bacaan pertama, tertinggi, terendah, dan terakhir, dengan nama kolom open, high, low, dan close. Nama kolom itu berasal dari istilah pasar modal, tetapi mekanismenya netral karena yang dihitung hanyalah nilai pertama, maksimum, minimum, dan terakhir setiap kelompok waktu. Method ini dipanggil pada satu kolom numerik sebagaimana contoh berikut, dan empat kolom hasilnya terbentuk dalam satu panggilan.

python Empat statistik per jam dengan ohlc
import pandas as pd

df = pd.read_csv("sensor_log.csv", parse_dates=["waktu"]).set_index("waktu")
empat = df["suhu_c"].resample("h").ohlc()
print(empat.head(4))
text Keluaran
                     open  high   low  close
waktu
2026-01-05 07:00:00  21.5  22.5  21.5   22.5
2026-01-05 08:00:00  24.6  25.9  22.6   25.9
2026-01-05 09:00:00  23.5  25.1  22.6   23.7
2026-01-05 10:00:00  22.6  25.3  21.4   21.4

Pada kelompok pertama, open bernilai 21.5 karena bacaan pukul 07.00 adalah yang pertama, close bernilai 22.5 dari bacaan pukul 07.45 yang terakhir, dan high serta low menangkap rentangnya. Kelompok pukul 10.00 memperlihatkan pola yang berbeda, yaitu close sebesar 21.4 jauh di bawah open sebesar 22.6, sehingga keempat kolom ini meringkas arah pergerakan dalam jam tersebut. Bentuk empat kolom ini lebih informatif daripada satu rata-rata ketika arah perubahan antar bacaan perlu diamati. Perhatikan pula bahwa open kelompok berikutnya tidak melanjutkan close kelompok sebelumnya, yaitu 24.6 pada pukul 08.00 sesudah close 22.5 pada pukul 07.00, karena keduanya diambil dari bacaan yang berbeda dan bukan satu deret nilai yang berkesinambungan.

Kesalahan umum#

Method resample gagal dengan TypeError bila dipanggil pada kolom biasa yang indexnya belum bertipe datetime, karena kelompok waktunya ditentukan oleh label index. Bila set_index terlewat, kolom masih membawa index angka bawaan bernama RangeIndex, dan pesan errornya menyebutkan hal itu secara eksplisit. Blok berikut menunjukkan kegagalan itu beserta perbaikannya.

python resample tanpa set_index dan perbaikannya
import pandas as pd

df = pd.read_csv("sensor_log.csv", parse_dates=["waktu"])
try:
    df["suhu_c"].resample("h")
except TypeError as e:
    print(type(e).__name__, ":", e)
per_jam = df.set_index("waktu")["suhu_c"].resample("h").mean()
print(per_jam.head(2))
text Keluaran
TypeError : Only valid with DatetimeIndex, TimedeltaIndex or PeriodIndex, but got an instance of 'RangeIndex'
waktu
2026-01-05 07:00:00    21.950
2026-01-05 08:00:00    24.125
Freq: h, Name: suhu_c, dtype: float64

Pesan TypeError menyebut RangeIndex, yaitu index angka 0, 1, dan seterusnya yang melekat pada kolom sebelum set_index dipanggil. Rangkaian df.set_index("waktu")["suhu_c"].resample("h").mean() pada baris terakhir blok menunjukkan urutan yang benar, yaitu index dibentuk terlebih dahulu, kolom dipilih, baru resample dan agregasinya dijalankan. Pola ini identik dengan syarat penyaringan string parsial pada topik DatetimeIndex, sehingga kebiasaan memeriksa dtype index sebelum operasi berbasis waktu selalu berguna. Pemeriksaan df.index.dtype yang sekali dijalankan menyingkat pencarian penyebabnya ketika pesan serupa muncul kembali pada analisis yang lebih panjang.

Ringkasan#

  • resample("h") membagi DatetimeIndex menjadi kelompok satu jam dan mean menghasilkan satu rata-rata per kelompok dengan label tepi awal periodenya.
  • resample("D") membagi per hari kalender, dan .agg(["min", "mean", "max"]) menerapkan beberapa fungsi sekaligus dengan nama kolom hasil mengikuti nama fungsinya.
  • ohlc() menghasilkan empat statistik per kelompok, yaitu bacaan pertama, tertinggi, terendah, dan terakhir, pada satu kolom numerik.
  • resample menuntut DatetimeIndex, sehingga set_index("waktu") harus mendahuluinya dan pesan TypeError menunjuk RangeIndex bila terlewat.

Referensi#