Tabel pola pada Bagian 3 menjawab pertanyaan analisis, tetapi pembaca laporan biasanya menginginkan format yang lebih padat: angka per pekan, satu matriks kota x bulan, dan beberapa statistik kunci. Bagian penutup proyek ini mengubah 270 baris harian menjadi ringkasan seperti itu dengan resample("W") dan pivot_table(), memeriksa strukturnya dengan describe(), lalu mengekspor dua berkas CSV lengkap dengan pemeriksaan baca-ulang. Proyek ditutup dengan narasi temuan — kebiasaan yang membedakan analisis dari sekadar tabel.
"""Merangkum data cuaca: agregasi mingguan, pivot kota x bulan, statistik, ekspor CSV."""
from pathlib import Path
import tempfile
import pandas as pd
from buat_cuaca import buat_cuaca, muat_bersih
if __name__ == "__main__":
with tempfile.TemporaryDirectory() as folder_hasil:
folder = Path(folder_hasil)
berkas = folder / "cuaca.csv"
buat_cuaca().to_csv(berkas, index=False)
df = muat_bersih(pd.read_csv(berkas))
df["bulan"] = df["tanggal"].dt.strftime("%Y-%m")
# 1. agregasi mingguan (contoh: Bandung)
bandung = df[df["kota"] == "Bandung"].set_index("tanggal")
mingguan = bandung.resample("W").agg(
suhu_rata=("suhu_max", "mean"),
hujan_total=("curah_hujan", "sum"),
).round(1)
print("== Ringkasan mingguan Bandung (resample W) ==")
print(mingguan.to_string())
# 2. pivot kota x bulan
pivot_suhu = pd.pivot_table(
df, index="kota", columns="bulan", values="suhu_max", aggfunc="mean"
).round(1)
pivot_hujan = pd.pivot_table(
df, index="kota", columns="bulan", values="curah_hujan", aggfunc="sum"
).round(1)
print("\n== Pivot rata-rata suhu_max (kota x bulan) ==")
print(pivot_suhu.to_string())
print("\n== Pivot total curah_hujan (kota x bulan) ==")
print(pivot_hujan.to_string())
# 3. statistik ringkas per kota
stat = df.groupby("kota")["suhu_max"].describe().round(2)
print("\n== Statistik suhu_max per kota ==")
print(stat.to_string())
# 4. ekspor ringkasan lalu baca ulang
berkas_mingguan = folder / "ringkasan_mingguan_bandung.csv"
berkas_hujan = folder / "pivot_hujan_bulanan.csv"
mingguan.to_csv(berkas_mingguan, index_label="pekan_berakhir")
pivot_hujan.to_csv(berkas_hujan)
baca_mingguan = pd.read_csv(berkas_mingguan)
baca_hujan = pd.read_csv(berkas_hujan, index_col=0)
print("\n== Ekspor ringkasan ke CSV ==")
print(
f"ringkasan_mingguan_bandung.csv: {len(baca_mingguan)} baris, "
f"kolom {list(baca_mingguan.columns)}"
)
print(
f"pivot_hujan_bulanan.csv : {baca_hujan.shape[0]} baris x "
f"{baca_hujan.shape[1]} kolom"
)
# 5. narasi temuan utama
kota_bulan = pivot_suhu.stack().idxmax()
suhu_tertinggi = pivot_suhu.stack().max()
kota_terhujam = pivot_hujan.sum(axis=1).idxmax()
hujan_terbanyak = int(pivot_hujan.sum(axis=1).max())
pekan_terbasah = mingguan["hujan_total"].idxmax().date()
print("\n== Temuan utama ==")
print(
f"kota-bulan terpanas : {kota_bulan[0]} {kota_bulan[1]} "
f"(rata-rata suhu_max {suhu_tertinggi} derajat)"
)
print(
f"kota terhujam : {kota_terhujam} "
f"(total {hujan_terbanyak} mm Januari-Maret)"
)
print(f"pekan terbasah Bandung: berakhir {pekan_terbasah}")Output yang Dihasilkan:
== Ringkasan mingguan Bandung (resample W) ==
suhu_rata hujan_total
tanggal
2026-01-04 27.8 11.3
2026-01-11 27.3 25.4
2026-01-18 26.7 75.7
2026-01-25 27.3 93.0
2026-02-01 26.5 18.9
2026-02-08 27.5 47.6
2026-02-15 27.6 30.4
2026-02-22 27.3 16.8
2026-03-01 27.5 83.9
2026-03-08 27.4 49.9
2026-03-15 26.5 10.5
2026-03-22 26.9 49.8
2026-03-29 27.3 23.9
2026-04-05 29.2 8.4
== Pivot rata-rata suhu_max (kota x bulan) ==
bulan 2026-01 2026-02 2026-03
kota
Bandung 27.1 27.4 27.2
Medan 32.5 32.4 32.2
Yogyakarta 31.4 31.5 31.7
== Pivot total curah_hujan (kota x bulan) ==
bulan 2026-01 2026-02 2026-03
kota
Bandung 224.3 175.1 146.1
Medan 221.4 132.5 97.6
Yogyakarta 154.6 194.8 158.3
== Statistik suhu_max per kota ==
count mean std min 25% 50% 75% max
kota
Bandung 90.0 27.22 1.25 24.0 26.52 27.2 28.00 30.5
Medan 90.0 32.37 1.04 30.1 31.72 32.5 33.08 34.8
Yogyakarta 90.0 31.55 1.15 28.2 30.80 31.6 32.10 35.2
== Ekspor ringkasan ke CSV ==
ringkasan_mingguan_bandung.csv: 14 baris, kolom ['pekan_berakhir', 'suhu_rata', 'hujan_total']
pivot_hujan_bulanan.csv : 3 baris x 3 kolom
== Temuan utama ==
kota-bulan terpanas : Medan 2026-01 (rata-rata suhu_max 32.5 derajat)
kota terhujam : Bandung (total 545 mm Januari-Maret)
pekan terbasah Bandung: berakhir 2026-01-25Ringkasan Mingguan dengan resample W #
Bagian pertama skrip merangkum Bandung per pekan: df[df["kota"] == "Bandung"].set_index("tanggal").resample("W") membagi 90 hari menjadi 14 kelompok yang berakhir pada hari Minggu, lalu agg() menghitung rata-rata suhu_max dan total curah_hujan tiap kelompok. Dua bin di tepi perlu dibaca hati-hati. Bin pertama (berakhir 2026-01-04) hanya berisi empat hari karena 1 Januari 2026 jatuh pada Kamis, dan bin terakhir berlabel 2026-04-05 hanya berisi data 30-31 Maret; itulah mengapa rata-rata suhunya melonjak ke 29.2 — dua hari saja, bukan tujuh. Bin parsial seperti ini wajar pada resample("W"), dan pembaca laporan perlu tahu bahwa dua angka di tepi dihitung dari sampel yang lebih sedikit.
Matriks Kota x Bulan dengan pivot_table #
Rekap bulanan Bagian 3 berbentuk daftar panjang berindex ganda; laporan lebih suka matriks. Skrip menambahkan kolom bantu bulan dari df["tanggal"].dt.strftime("%Y-%m"), lalu pd.pivot_table() menyusunnya: index="kota" sebagai baris, columns="bulan", dan values yang diagregasi. Dua matriks dibuat: rata-rata suhu_max dan total curah_hujan. Angka keduanya identik dengan tabel resample Bagian 3 — bukan kebetulan, melainkan validasi silang alami karena dua jalan berbeda menghitung agregasi yang sama.
Matriks hujan memudahkan perbandingan sekilas: kolom Januari menunjukkan tiga kota hampir serupa (224.3, 221.4, 154.6 mm), tetapi Maret memisahkan mereka tajam (146.1, 97.6, 158.3 mm), dan baris Yogyakarta membentuk lembah-puncak-lembah yang tidak dimiliki dua kota lain.
Statistik Ringkas per Kota #
Sebelum diekspor, struktur data diperiksa sekali lagi dengan df.groupby("kota")["suhu_max"].describe(). Keluarannya delapan statistik per kota: count 90 untuk semua kota membuktikan kalender utuh hasil Bagian 2, mean 27.22 untuk Bandung berbanding 32.37 Medan dan 31.55 Yogyakarta, sementara std 1.04-1.25 menunjukkan variansi suhu yang mirip. Rentang min-max juga menegaskan kembali temuan idxmax/idxmin Bagian 3 tanpa perlu menghitung ulang.
Mengekspor dan Memeriksa Ringkasan #
Ringkasan baru berguna bila bisa keluar dari Python. mingguan.to_csv() menulis ringkasan_mingguan_bandung.csv dengan index_label="pekan_berakhir" agar kolom index punya nama saat dibaca ulang, dan pivot_hujan.to_csv() menulis pivot_hujan_bulanan.csv. Kedua berkas langsung dibaca kembali dengan read_csv(): tabel mingguan kembali utuh 14 baris dengan tiga kolom, dan matriks hujan kembali 3 baris x 3 kolom. Seluruh proses berlangsung di dalam TemporaryDirectory, pola yang Anda pakai sejak Bagian 1 — pada pekerjaan nyata ganti path dengan folder laporan Anda.
Temuan dan Penutup Proyek #
Bagian akhir skrip menyusun narasi dari angka-angka yang sudah dihitung: kota-bulan terpanas adalah Medan Januari (rata-rata suhu_max 32.5 derajat), kota dengan total hujan tertinggi adalah Bandung (545 mm selama tiga bulan), dan pekan terbasah Bandung adalah pekan yang berakhir 25 Januari (93.0 mm). Narasi ini yang akan dibacakan, sementara tabel-tabel di atas menjadi lampirannya.
Proyek Analisis Data Cuaca kini tuntas. Satu berkas mentah 268 baris dengan enam masalah berubah menjadi dataset utuh 270 baris, lalu menjadi pola mingguan-bulanan dan ringkasan yang terekspor. Bekal yang Anda pakai — memuat CSV, menangani data hilang dalam dua wujudnya, groupby() dengan resample() dan rolling(), boolean mask, pivot_table(), hingga ekspor tervalidasi — adalah bekal yang sama untuk proyek berikutnya, Proyek: Eksplorasi Dataset Terbuka. Bedanya, di sana data tidak lagi dibuat oleh generator: Bagian 1 mengajak Anda memilih dan memahami dataset terbuka yang nyata sebelum membersihkan dan mengeksplorasinya pada bagian-bagian berikutnya.
Sumber bacaan resmi: pandas.pivot_table , pandas.DataFrame.to_csv , dan pandas.DataFrame.describe .