Data yang baru terekstrak hampir tidak pernah siap dianalisis. Nilai uang masih berupa string "Rp1.250.000", tanggal masih berformat "28/09/2026", nama pelanggan bercampur kapital dan spasi, dan laporan yang diminta manajemen membutuhkan kolom yang sama sekali belum ada di sumber. Transformasi adalah tahap yang menyelesaikan semua itu: mengubah data mentah menjadi dataset yang bertipe benar, berformat seragam, dan berstruktur sesuai kebutuhan analisis. Chapter ini memetakan kategori transformasi yang umum dipakai, lalu membuktikannya dengan contoh nyata pada data transaksi toko.

Lima Kategori Transformasi Umum #

KategoriPeranContoh pada toko online
Cleaningmerapikan nilai yang kotorbuang spasi berlebih, seragamkan kapitalisasi nama
Konversi tipemengubah tipe data kolom"250000" menjadi int, "28/09/2026" menjadi date
Derivasi kolommembuat kolom baru dari kolom lamakuartal dari tanggal, segmen dari total belanja
Agregasimerangkum banyak baris menjadi lebih sedikittotal pendapatan per kota
Joinmenggabungkan dua sumber datamemperkaya transaksi dengan pulau dari tabel kota

Lima kategori tersebut bukan tahapan berurutan, melainkan perbendaharaan langkah — satu pipeline bisa memakai cleaning dan konversi untuk setiap baris, lalu agregasi di ujung. Urutan penerapannya biasanya mengikuti ketergantungan data: cleaning dan konversi tipe dikerjakan lebih dulu karena langkah lain membutuhkan nilai yang sudah rapi dan bertipe benar; derivasi kolom menyusul karena rumusnya membaca hasil konversi; agregasi diletakkan di ujung karena merangkas baris yang sudah lengkap. Join bisa masuk di mana saja tergantung arahnya — memperkaya fakta dengan dimensi biasanya sebelum agregasi, sedangkan penggabungan dua hasil ringkasan justru setelahnya; pola ini dibahas mendalam pada chapter Join dan Agregasi Data. Menempatkan langkah di urutan yang salah tidak selalu memicu galat; lebih sering hasilnya terdengar masuk akal padahal salah, misalnya rata-rata yang dihitung sebelum baris ganda dibuang.

Contoh Nyata: Bersihkan, Konversi, Hitung #

Skenarionya standar: data transaksi diekstrak dari sistem operasional dalam format teks. Nilai uang memakai awalan Rp dan pemisah ribuan titik; tanggal memakai format dd/mm/yyyy; nama pelanggan datang dari tiga aplikasi berbeda sehingga kapitalisasi tidak konsisten. Ringkasan sebelum-sesudahnya tampak seperti ini:

Nilai masukanHasil transformasiKategori
" budi ""Budi"cleaning
"Rp1.250.000"1250000 (int)konversi tipe
"28/09/2026"date(2026, 9, 28)konversi tipe
kolom kuartal (belum ada)3 untuk bulan Septemberderivasi

Tiga kategori pertama bekerja per baris; agregasi dan join bekerja lintas baris. Perbedaan ini nanti menentukan pilihan alat, karena SQL unggul pada operasi set-based sementara Python unggul pada keputusan bertingkat per baris — perbandingannya dibahas pada chapter Transformasi dengan SQL. Kode berikut membersihkan ketiganya, menurunkan kolom kuartal, lalu menghitung total per kota.

python transformasi: cleaning, konversi, derivasi, agregasi
from datetime import date

# Data mentah hasil ekstraksi: tipe masih string, format belum seragam
transaksi_mentah = [
    {"tanggal": "28/09/2026", "pelanggan": "  budi ", "kota": "Jakarta ", "nilai": "Rp1.250.000"},
    {"tanggal": "05/10/2026", "pelanggan": "siti", "kota": "Bandung", "nilai": "Rp980.000"},
    {"tanggal": "12/10/2026", "pelanggan": "DEWI", "kota": "Jakarta", "nilai": "Rp2.100.000"},
    {"tanggal": "02/10/2026", "pelanggan": "andi", "kota": "Surabaya", "nilai": "Rp640.000"},
]


def ke_date(tanggal_str):
    """Konversi 'dd/mm/yyyy' menjadi objek date."""
    hari, bulan, tahun = tanggal_str.split("/")
    return date(int(tahun), int(bulan), int(hari))


def ke_rupiah(nilai_str):
    """Konversi 'Rp1.250.000' menjadi bilangan bulat."""
    return int(nilai_str.replace("Rp", "").replace(".", ""))


# Cleaning + konversi tipe + derivasi kolom kuartal
transaksi_bersih = []
for t in transaksi_mentah:
    tanggal = ke_date(t["tanggal"])
    transaksi_bersih.append({
        "tanggal": tanggal,
        "pelanggan": t["pelanggan"].strip().title(),
        "kota": t["kota"].strip(),
        "nilai": ke_rupiah(t["nilai"]),
        "kuartal": (tanggal.month - 1) // 3 + 1,
    })

for t in transaksi_bersih:
    rupiah = f"Rp{t['nilai']:,}".replace(",", ".")  # 1250000 -> Rp1.250.000
    print(t["tanggal"], t["pelanggan"], t["kota"], rupiah, f"Q{t['kuartal']}")

# Agregasi: total nilai transaksi per kota
total_per_kota = {}
for t in transaksi_bersih:
    total_per_kota[t["kota"]] = total_per_kota.get(t["kota"], 0) + t["nilai"]
print("Total per kota:", total_per_kota)

Output yang Dihasilkan:

text
2026-09-28 Budi Jakarta Rp1.250.000 Q3
2026-10-05 Siti Bandung Rp980.000 Q4
2026-10-12 Dewi Jakarta Rp2.100.000 Q4
2026-10-02 Andi Surabaya Rp640.000 Q4
Total per kota: {'Jakarta': 3350000, 'Bandung': 980000, 'Surabaya': 640000}

Mari kita telaah baris-baris kode di atas:

  1. Baris 4-9 (data mentah): setiap nilai masih berupa string; inilah kondisi umum hasil ekstraksi dari CSV atau API.
  2. Baris 12-15 (ke_date): string tanggal dipecah berdasarkan /, lalu tiga bagiannya dikonversi menjadi objek date — objek ini bisa dibandingkan, diurutkan, dan dihitung selisihnya, hal yang mustahil dilakukan pada string.
  3. Baris 18-20 (ke_rupiah): awalan Rp dan pemisah ribuan dibuang sebelum int() mengubah sisanya menjadi bilangan; hasilnya bisa dijumlahkan.
  4. Baris 29-30 (cleaning): strip().title() mengubah " budi " menjadi "Budi" dan membuang spasi di ujung "Jakarta ".
  5. Baris 32 (derivasi): rumus (bulan - 1) // 3 + 1 menurunkan kuartal dari bulan — September jatuh di Q3, Oktober di Q4; kolom ini sebelumnya tidak ada di sumber.
  6. Baris 40-42 (agregasi): dictionary total_per_kota merangkum nilai per kota; dict.get(kunci, 0) mengembalikan nol saat kota belum pernah muncul sehingga penjumlahan tetap benar.

Urutan operasi pada ke_rupiah juga penting: kedua replace harus selesai sebelum int() dipanggil — sisa karakter non-digit membuat int() langsung menggalat ValueError. Konversi yang gagal pada satu baris sebaiknya ditangani sebagai data bermasalah yang dicatat, bukan dibiarkan menghentikan seluruh pipeline.

Perhatikan baris pertama output: transaksi 28 September menghasilkan Q3 sedangkan tiga lainnya Q4 — derivasi bekerja per baris, bukan sekali untuk seluruh tabel.

Baris terakhir output juga layak dicermati: total Jakarta 3.350.000 adalah penjumlahan 1.250.000 + 2.100.000 dari dua transaksi Jakarta, sedangkan Surabaya hanya menyimpan satu transaksi karena memang hanya ada satu. Kunci agregasi sengaja dipilih per kota — bukan per pelanggan — karena pertanyaan bisnisnya menanyakan wilayah, bukan orang. Menetapkan kunci dan granularitas sebelum menulis kode mencegah kita merangkas dengan tingkat yang keliru.

Satu aturan penting untuk ditutup: transformasi sebaiknya deterministik — input yang sama harus menghasilkan output yang sama. Aturan ini membuat pipeline aman dijalankan ulang saat terjadi kegagalan, dan menjadi prasyarat saat kita membahas Incremental Transformation di akhir section ini. Konversi tanggal memakai modul datetime yang didokumentasikan di docs.python.org .

Data transaksi kini bersih dan tervalidasi di memori. Langkah berikutnya adalah menyimpannya agar bisa diquery oleh orang lain — pilihan pola pemuatan menentukan kesegaran data dan durasi proses. Kita lanjut ke chapter Pemuatan Data.