Datetime di Pandas: to_datetime & .dt
Ubah teks jadi tanggal betulan, pecah jadi tahun/bulan/hari, dan agregasi per periode dengan resample.
Dari Teks Mati jadi Tanggal Hidup
Kolom tanggal yang tipenya teks itu seperti kalender yang digambar di kertas: kelihatan, tapi tidak bisa dipakai menghitung. Setelah dikonversi jadi datetime, kolom itu jadi "hidup": bisa diurutkan kronologis, diselisihi, dipecah jadi tahun/bulan/hari, dan diagregasi per minggu atau bulan.
Kenapa penting untuk data analyst? Karena hampir semua pertanyaan bisnis berbau waktu: tren penjualan bulanan, perbandingan kuartal ini vs kuartal lalu, hari apa yang paling ramai. Semua itu mustahil (atau menyiksa) kalau kolom tanggal masih berupa string.
to_datetime(): Menghidupkan Kolom Tanggal
import pandas as pd
df = pd.DataFrame({
"tanggal": ["2024-01-05", "2024-01-12", "2024-02-03", "2024-02-20"],
"omzet": [500, 700, 600, 900],
})
df["tanggal"] = pd.to_datetime(df["tanggal"])
print(df["tanggal"].dtype) # datetime64[ns]Untuk format tanggal Indonesia (tanggal/bulan/tahun), tambahkan dayfirst=True atau format eksplisit:
df2 = pd.DataFrame({"tgl": ["05/01/2024", "12/01/2024", "03/02/2024"]})
# Cara 1: dayfirst
df2["tgl"] = pd.to_datetime(df2["tgl"], dayfirst=True)
# Cara 2: format eksplisit (lebih cepat dan tidak ambigu)
df2["tgl"] = pd.to_datetime(df2["tgl"], format="%d/%m/%Y")
print(df2["tgl"].tolist())Accessor .dt: Memecah Tanggal
Setelah jadi datetime, accessor .dt membuka semua komponennya.
df["tahun"] = df["tanggal"].dt.year
df["bulan"] = df["tanggal"].dt.month
df["nama_bulan"] = df["tanggal"].dt.month_name()
df["hari"] = df["tanggal"].dt.day
df["nama_hari"] = df["tanggal"].dt.day_name()
df["kuartal"] = df["tanggal"].dt.quarter
print(df[["tanggal", "nama_hari", "kuartal"]])Contoh realistis, mencari hari tersibuk dalam seminggu:
df = pd.DataFrame({
"tanggal": pd.to_datetime(["2024-01-01", "2024-01-02", "2024-01-08",
"2024-01-09", "2024-01-09", "2024-01-15"]),
"pengunjung": [120, 150, 130, 170, 160, 140],
})
df["hari"] = df["tanggal"].dt.day_name()
tersibuk = df.groupby("hari")["pengunjung"].sum().sort_values(ascending=False)
print(tersibuk)resample(): Agregasi per Periode Waktu
resample() adalah groupby khusus waktu. Syaratnya: kolom tanggal jadi index dulu (atau pakai parameter on).
df = pd.DataFrame({
"tanggal": pd.to_datetime(["2024-01-05", "2024-01-12", "2024-01-20",
"2024-02-03", "2024-02-15", "2024-03-01"]),
"omzet": [500, 700, 600, 900, 800, 1000],
})
df = df.set_index("tanggal")
# Omzet per bulan (ME = month-end)
per_bulan = df.resample("ME").sum()
print(per_bulan)
# omzet
# tanggal
# 2024-01-31 1800
# 2024-02-29 1700
# 2024-03-31 1000
# Rata-rata per minggu
per_minggu = df.resample("W").mean()
print(per_minggu)Kode frekuensi yang paling sering dipakai: "D" harian, "W" mingguan, "ME" bulanan, "QE" kuartalan, "YE" tahunan.
Catatan teknis:
resamplemengisi periode yang kosong dengan NaN (bukan menghilangkannya). Ini justru berguna: kamu bisa melihat bulan mana yang tidak ada transaksi sama sekali, lalu memutuskan denganfillna(0)atau membiarkannya.
Jebakan Umum
SALAH, mengurutkan tanggal yang masih string:
# Jangan: urutan alfabet, bukan kronologis!
s = pd.Series(["05/01/2024", "12/01/2024", "03/02/2024"])
print(s.sort_values().tolist())
# ['03/02/2024', '05/01/2024', '12/01/2024'] <- salah urutan!BENAR, konversi dulu baru urutkan:
# Lakukan: datetime diurutkan dengan benar
s = pd.Series(["05/01/2024", "12/01/2024", "03/02/2024"])
s = pd.to_datetime(s, format="%d/%m/%Y")
print(s.sort_values().dt.strftime("%d/%m/%Y").tolist())
# ['05/01/2024', '12/01/2024', '03/02/2024'] <- kronologis benarSALAH, resample tanpa datetime index:
# Jangan: kolom tanggal masih kolom biasa
df = pd.DataFrame({"tanggal": ["2024-01-05"], "omzet": [500]})
df.resample("ME", on="tanggal").sum() # TypeError: tanggal bukan datetimeBENAR, konversi dulu atau set sebagai index:
# Lakukan: pastikan datetime sebelum resample
df = pd.DataFrame({"tanggal": ["2024-01-05", "2024-02-10"], "omzet": [500, 700]})
df["tanggal"] = pd.to_datetime(df["tanggal"])
print(df.resample("ME", on="tanggal").sum())Tantangan
Tren omzet bulanan dari data harian
Diberi DataFrame dengan kolom tanggal ["2024-01-05", "2024-01-20", "2024-02-03", "2024-02-18", "2024-03-10"] dan omzet [500, 700, 600, 900, 1000]. Konversi tanggal jadi datetime, jadikan index, lalu resample per bulan ("ME") untuk total omzet. Cetak hasilnya.
Kuis Bab
Uji pemahamanmu: Bab 6: Data Cleaning dan Transformasi
Jawab 5 soal berikut, lalu tekan "Periksa Jawaban".
1.Apa yang dikembalikan df.isna().sum()?
2.Kapan sebaiknya memakai drop_duplicates()?
3.Dalam metode IQR, nilai dianggap outlier jika...
4.Apa beda pd.merge(df_a, df_b, how='left') dengan how='inner'?
5.Kenapa kolom tanggal string perlu diubah dengan pd.to_datetime()?