Pandas & NumPy Academy · Pelajaran

Menyusun Langkah Transformasi sebagai Fungsi

Pecah notebook Anda menjadi fungsi ekstraksi, transformasi, dan pemuatan, yang masing-masing menerima serta mengembalikan DataFrame agar mudah diuji.

Pelajaran 1 dari 413 langkah

Menyusun Langkah Transformasi sebagai Fungsi adalah pelajaran Pandas & NumPy Academy gratis di CoddyKit. Ini adalah pelajaran 1 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Pandas & NumPy Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Pandas & NumPy Academy mencakup 4 pelajaran total.

Melampaui Notebook

Notebook Jupyter sangat baik untuk eksplorasi, tetapi kurang cocok untuk alur kerja data produksi. Kode yang tersebar di 50 sel dengan keadaan global dan tanpa pengujian bersifat rapuh: mengubah satu sel dapat secara diam-diam merusak sel lainnya. Alternatif profesionalnya adalah mengekstrak setiap transformasi menjadi fungsi bernama yang menerima DataFrame dan mengembalikan DataFrame. Pemisahan tanggung jawab ini merupakan dasar kode rekayasa data yang mudah dipelihara.

# Notebook-style (fragile)
df = pd.read_csv('orders.csv')
df = df.dropna(subset=['revenue'])
df = df[df['quantity'] > 0]
df['revenue_per_unit'] = df['revenue'] / df['quantity']

# Function-style (robust)
def extract(path):
    return pd.read_csv(path)

def transform(df):
    return (
        df.dropna(subset=['revenue'])
        .query('quantity > 0')
        .assign(revenue_per_unit=lambda d: d['revenue'] / d['quantity'])
    )

df = transform(extract('orders.csv'))

Pola ETL: Ekstrak, Transformasi, Muat

Pola ETL membagi alur kerja data menjadi tiga tahap: Ekstrak (membaca dari sumber), Transformasi (membersihkan dan memperkaya), serta Muat (menulis ke tujuan). Setiap tahap merupakan fungsi terpisah. Pemisahan ini memudahkan penggantian sumber data (CSV atau basis data), perubahan logika pembersihan, atau perubahan format keluaran tanpa menyentuh dua tahap lainnya. Setiap alur kerja produksi sebaiknya mengikuti struktur ini.

def extract(config):
    return pd.read_csv(config['input_path'], parse_dates=['order_date'])

def transform(df, config):
    return (
        df
        .dropna(subset=config['required_cols'])
        .query('quantity > 0')
        .assign(revenue=lambda d: d['quantity'] * d['unit_price'])
    )

def load(df, config):
    df.to_parquet(config['output_path'], index=False)
    print(f'Saved {len(df)} rows.')

Prinsip Tanggung Jawab Tunggal

Setiap fungsi transformasi harus melakukan tepat satu hal. Fungsi bernama clean_data() yang menghapus nilai kosong, membatasi pencilan, menguraikan tanggal, dan menyandikan kategori akan sulit diuji dan di-debug. Sebagai gantinya, tulis drop_nulls(), cap_outliers(), parse_dates(), dan encode_categories() sebagai fungsi terpisah. Perincian ini memudahkan Anda melewati, mengganti, atau mengurutkan ulang setiap langkah.

def drop_null_rows(df, required_cols):
    return df.dropna(subset=required_cols)

def remove_returns(df):
    return df[df['quantity'] > 0]

def compute_revenue(df):
    return df.assign(revenue=lambda d: d['quantity'] * d['unit_price'])

def add_date_features(df):
    return df.assign(
        year=lambda d: d['order_date'].dt.year,
        month=lambda d: d['order_date'].dt.month
    )

Merangkai Langkah dengan pipe()

Hubungkan fungsi-fungsi dengan tanggung jawab tunggal menggunakan pipe() untuk membangun seluruh tahap transformasi sebagai rangkaian yang mudah dibaca. Rangkaian tersebut terbaca seperti resep: setiap baris merupakan satu langkah, dan aliran data bergerak dari atas ke bawah. Langkah apa pun dapat diberi komentar atau diurutkan ulang tanpa mengganti nama variabel. Hasil akhirnya adalah DataFrame yang bersih dan diperkaya, siap untuk tahap pemuatan.

import pandas as pd

REQUIRED = ['order_id', 'revenue', 'order_date']

def transform(raw_df):
    return (
        raw_df
        .pipe(drop_null_rows, required_cols=REQUIRED)
        .pipe(remove_returns)
        .pipe(compute_revenue)
        .pipe(add_date_features)
    )

df_clean = transform(pd.read_csv('orders.csv', parse_dates=['order_date']))
print(df_clean.shape)

Mengembalikan Jumlah Baris untuk Audit

Setiap fungsi transformasi sebaiknya secara opsional mencatat jumlah baris yang diterima dan dikembalikan. Membungkus isi fungsi dengan pencatatan jumlah baris sebelum dan sesudah merupakan jejak audit ringan yang memungkinkan Anda melihat dengan cepat di mana baris dihapus dalam suatu proses alur kerja. Simpan jumlah tersebut dalam sebuah daftar dan cetak sebagai laporan di akhir setiap proses.

audit_log = []

def audited(func):
    def wrapper(df, *args, **kwargs):
        before = len(df)
        result = func(df, *args, **kwargs)
        after = len(result)
        audit_log.append({'step': func.__name__, 'in': before, 'out': after, 'dropped': before - after})
        return result
    return wrapper

@audited
def drop_null_rows(df, required_cols):
    return df.dropna(subset=required_cols)

Fungsi yang Dapat Diuji dengan DataFrame Kecil

Keuntungan terbesar fungsi bernama adalah kemudahan pengujiannya. Tulis DataFrame pengujian kecil yang mewakili kasus khusus yang realistis, lalu pastikan keluaran fungsi benar. Uji fungsi drop_null_rows dengan satu baris yang memiliki nilai kosong dan pastikan baris tersebut dihapus, lalu gunakan baris lain tanpa nilai kosong dan pastikan baris itu dipertahankan. Pengujian unit pada fungsi transformasi dapat mendeteksi regresi ketika kode alur kerja berubah.

import pandas as pd

def test_drop_null_rows():
    test_df = pd.DataFrame({
        'order_id': [1, 2, 3],
        'revenue': [100.0, None, 200.0]
    })
    result = drop_null_rows(test_df, required_cols=['revenue'])
    assert len(result) == 2, 'Should have 2 non-null rows'
    assert result['revenue'].isna().sum() == 0, 'No nulls in revenue'
    print('test_drop_null_rows PASSED')

test_drop_null_rows()

Mengatur Fungsi ke dalam Modul

Seiring bertambah besarnya alur kerja, pisahkan fungsi ke dalam berkas modul Python: extract.py, transform.py, load.py, dan validate.py. Skrip utama pipeline.py mengimpor dan mengoordinasikan semuanya. Struktur berkas ini mudah dibaca, dapat diuji dengan pytest, dan dapat diterapkan sebagai paket Python. Struktur ini mencerminkan tata letak standar yang digunakan oleh tim rekayasa data dengan alat seperti dbt atau Airflow.

# pipeline.py
# from extract import extract_orders
# from transform import transform
# from load import load_to_parquet
# from validate import validate_sales_df

# def run_pipeline(config):
#     raw = extract_orders(config)
#     clean = transform(raw, config)
#     validate_sales_df(clean)
#     load_to_parquet(clean, config)

print('Module-based pipeline structure shown above (imports commented for demo)')

Idempotensi: Menjalankan Berulang Kali dengan Aman

Fungsi alur kerja yang dirancang dengan baik bersifat idempoten: menjalankannya dua kali pada masukan yang sama menghasilkan keluaran yang sama dan tidak menimbulkan efek samping. Hindari mutasi langsung (df.drop(..., inplace=True)) dan selalu gunakan df.copy() di awal fungsi yang mengubah kolom. Fungsi idempoten dapat dijalankan ulang setelah kegagalan tanpa merusak data keluaran.

def add_revenue_flag(df, threshold=500):
    # Use copy to avoid mutating the input
    df = df.copy()
    df['is_large_order'] = df['revenue'] >= threshold
    return df

# Running twice gives the same result
df1 = add_revenue_flag(df_clean)
df2 = add_revenue_flag(df_clean)
assert df1.equals(df2), 'Function is not idempotent!'
print('Idempotency check passed.')

Petunjuk Tipe untuk Dokumentasi Mandiri

Tambahkan petunjuk tipe Python ke tanda tangan fungsi transformasi untuk memperjelas kontraknya: def transform(df: pd.DataFrame) -> pd.DataFrame. Petunjuk tipe mendokumentasikan dirinya sendiri — pengembang mana pun yang membaca fungsi tersebut akan mengetahui dengan tepat apa yang diharapkan dan dikembalikan tanpa perlu membaca isinya. Petunjuk ini juga memungkinkan alat analisis statis seperti mypy dan pelengkapan otomatis IDE mendeteksi kesalahan tipe sebelum waktu berjalan.

from typing import List

def drop_null_rows(df: pd.DataFrame, required_cols: List[str]) -> pd.DataFrame:
    return df.dropna(subset=required_cols)

def compute_revenue(df: pd.DataFrame) -> pd.DataFrame:
    return df.assign(revenue=lambda d: d['quantity'] * d['unit_price'])

print('Type-annotated functions ready for production use.')

Mendokumentasikan Setiap Langkah dengan Docstring

Setiap fungsi transformasi sebaiknya memiliki docstring satu baris yang menyatakan apa yang dilakukan fungsi tersebut, kolom apa yang diperlukan, serta kolom apa yang ditambahkan atau dihapus. Docstring yang baik membuat fungsi mudah ditemukan melalui help() dan keterangan alat di IDE. Docstring juga berfungsi sebagai dokumen spesifikasi: pernyataan yang gagal dan bertentangan dengan docstring merupakan bug; docstring yang tidak sesuai dengan kode merupakan kesalahan dokumentasi.

def compute_revenue(df: pd.DataFrame) -> pd.DataFrame:
    """Add 'revenue' column as quantity * unit_price.

    Requires: 'quantity' (numeric), 'unit_price' (numeric) columns.
    Returns: df with new 'revenue' float column appended.
    """
    return df.assign(revenue=lambda d: d['quantity'] * d['unit_price'])

help(compute_revenue)

Menjalankan Alur Kerja Lengkap

Koordinasikan ETL lengkap dengan memanggil ketiga tahap secara berurutan: ekstrak, transformasi, dan muat. Tambahkan pengukuran waktu di setiap tahap untuk mengetahui di mana waktu digunakan. Tangkap pengecualian dari setiap tahap secara terpisah agar pesan kesalahan menunjukkan tahap yang gagal. Catat waktu mulai dan selesai seluruh proses serta apakah proses tersebut berhasil atau gagal untuk keperluan pemantauan.

import time

CONFIG = {
    'input_path': 'orders.csv',
    'output_path': 'orders_clean.parquet',
    'required_cols': ['order_id', 'revenue']
}

t0 = time.time()
raw = extract(CONFIG)
clean = transform(raw, CONFIG)
load(clean, CONFIG)

print(f'Pipeline completed in {time.time()-t0:.1f}s')
print(f'Audit log: {audit_log}')

Pemeriksaan Cepat

Uji pemahaman Anda tentang konsep Analisis Data dari pelajaran ini.

Rangkuman Pelajaran

Dalam pelajaran ini Anda telah mempelajari: menyusun alur kerja sebagai fungsi ETL dengan tanggung jawab tunggal, membuat fungsi dapat diuji, idempoten, dan mendokumentasikan dirinya sendiri dengan petunjuk tipe serta docstring, serta mengoordinasikan seluruh alur kerja dengan pengukuran waktu dan pencatatan audit. Selanjutnya, kita akan membahas cara memberi parameter pada alur kerja menggunakan dict konfigurasi agar dapat digunakan kembali pada berbagai kumpulan data.

Gratis untuk memulai

Belajar Python dengan tutor AI — gratis

Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.

Kursus
30
Pelajaran
120

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Menyusun Langkah Transformasi sebagai Fungsi” gratis?

Ya — teks lengkap “Menyusun Langkah Transformasi sebagai Fungsi” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Pandas & NumPy Academy, upgrade ke CoddyKit PRO. Kursus Pandas & NumPy Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Menyusun Langkah Transformasi sebagai Fungsi”?

Pecah notebook Anda menjadi fungsi ekstraksi, transformasi, dan pemuatan, yang masing-masing menerima serta mengembalikan DataFrame agar mudah diuji. Kamu berlatih Pandas & NumPy Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Pandas & NumPy Academy?

Tidak diperlukan pengalaman sebelumnya. Pandas & NumPy Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 1 dari 4.

Berapa lama pelajaran “Menyusun Langkah Transformasi sebagai Fungsi” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Pandas & NumPy Academy ini?

Ya. Setiap pelajaran Pandas & NumPy Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Menyusun Langkah Transformasi sebagai Fungsi
  2. Membuat Pipeline Berparameter dengan Dict Konfigurasi
  3. Menguji Langkah Pipeline dengan Assertion
  4. Menjadwalkan dan Mencatat Proses Pipeline
← Kembali ke Pandas & NumPy Academy