Idenya
Data mentah jarang punya kolom yang persis dibutuhkan analisismu. Kamu akan menambah kolom hasil perhitungan (margin, PPN, penanda "order besar"), mengganti nama kolom export yang membingungkan (TGL_TRX → order_date), dan membuang kolom yang tidak dipakai siapa pun. Operasi-operasi ini sederhana, tapi melakukannya dengan bersih (di satu tempat, dengan nama yang jelas, tanpa efek samping yang mengejutkan) adalah yang membuat analisis mudah diikuti.
import pandas as pd
import numpy as np
sales = pd.read_csv("sales.csv")
lines = sales[["order_id", "product", "category", "quantity", "unit_price", "revenue", "status"]].copy()
.copy() membuat lines menjadi DataFrame yang independen, sehingga menambahkan kolom ke dalamnya tidak pernah memengaruhi sales (dan menghindari warning dari modul sebelumnya).
Menambahkan kolom hasil perhitungan
Assign ke nama kolom baru. Sisi kanannya biasanya berupa perhitungan tervektorisasi pada kolom lain:
lines["vat"] = (lines["revenue"] * 0.11).round().astype(int)
lines["revenue_incl_vat"] = lines["revenue"] + lines["vat"]
print(lines[["product", "revenue", "vat", "revenue_incl_vat"]].head(3))
product revenue vat revenue_incl_vat
0 Desk Organizer 89000 9790 98790
1 Arabica Gayo 250g 285000 31350 316350
2 Pour-over Kettle 960000 105600 1065600
.round() membulatkan, dan .astype(int) mengubah float kembali menjadi bilangan bulat. Satu nilai tunggal juga bisa: lines["currency"] = "IDR" mengisi setiap baris dengan nilai itu.
Kolom kondisional
Untuk pilihan dua arah, np.where(condition, value_if_true, value_if_false) dari NumPy adalah alat standarnya:
lines["size"] = np.where(lines["revenue"] >= 300000, "large", "small")
print(lines["size"].value_counts())
size
small 52
large 19
Name: count, dtype: int64
Untuk beberapa kelompok, pd.cut mengubah angka menjadi rentang berlabel:
lines["price_band"] = pd.cut(
lines["unit_price"],
bins=[0, 60000, 150000, float("inf")],
labels=["budget", "mid", "premium"],
)
print(lines[["product", "unit_price", "price_band"]].head(4))
product unit_price price_band
0 Desk Organizer 89000 mid
1 Arabica Gayo 250g 95000 mid
2 Pour-over Kettle 320000 premium
3 Scented Candle 75000 mid
bins adalah batas-batasnya: 0 sampai 60.000 adalah "budget", 60.000 sampai 150.000 "mid", dan apa pun di atasnya "premium". Setiap bin mengikutsertakan batas kanannya (jadi 60.000 dihitung sebagai budget).
Untuk pemetaan bebas, .map() dengan dictionary menerjemahkan nilai (modul 12 membahasnya secara lengkap):
category_owner = {"Coffee": "Maya", "Kitchen": "Maya", "Stationery": "Agus", "Electronics": "Agus", "Home": "Maya"}
lines["owner"] = lines["category"].map(category_owner)
assign: tambah kolom tanpa mengubah aslinya
df.assign(...) mengembalikan DataFrame baru dengan kolom tambahan. Ia tidak menyentuh df, sehingga sempurna untuk merangkai langkah-langkah (modul 20) dan untuk menjaga data asli tetap utuh:
enriched = lines.assign(
margin_rate=0.4,
est_margin=lambda d: (d["revenue"] * d["margin_rate"]).round().astype(int),
)
print(enriched[["revenue", "margin_rate", "est_margin"]].head(2))
print("est_margin" in lines.columns)
revenue margin_rate est_margin
0 89000 0.4 35600
1 285000 0.4 114000
False
Bentuk lambda d: ... menerima DataFrame sebagaimana yang sudah dibangun sejauh ini, jadi est_margin bisa memakai margin_rate, yang baru saja dibuat di assign yang sama.
Mengganti nama kolom
Ekspor dari sistem lain sering datang dengan nama kolom seperti TGL_TRX atau NM PRODUK, yang bermakna bagi pembuat sistem itu tapi canggung diketik dan sulit dibaca di kodemu. Mengganti namanya sekali, tepat setelah dimuat, membuat semua langkah sesudahnya lebih mudah. Berikan rename sebuah dictionary yang memetakan setiap nama lama ke nama barunya:
export = pd.DataFrame({"TGL_TRX": ["01/07/2024"], "NM PRODUK": ["Kopi Susu"], "Qty": [2]})
export = export.rename(columns={"TGL_TRX": "order_date", "NM PRODUK": "product", "Qty": "quantity"})
print(list(export.columns))
['order_date', 'product', 'quantity']
Untuk membersihkan semua nama sekaligus (huruf kecil, garis bawah alih-alih spasi), ubah label kolomnya secara langsung:
raw = pd.DataFrame(columns=["Order ID", " Customer Name ", "Total (Rp)"])
raw.columns = (
raw.columns.str.strip()
.str.lower()
.str.replace(r"[^a-z0-9]+", "_", regex=True)
.str.strip("_")
)
print(list(raw.columns))
['order_id', 'customer_name', 'total_rp']
Nama kolom snake_case yang konsisten berarti kamu tidak perlu mengingat apakah namanya "Total (Rp)" atau "total". Banyak analyst menjadikan ini baris pertama setelah setiap read_csv.
Membuang kolom
Kolom bantu yang hanya kamu butuhkan untuk perhitungan, seperti kolom PPN tadi, bisa membuat tabel akhir berantakan. drop membuang kolom-kolom yang kamu sebut:
slim = lines.drop(columns=["vat", "revenue_incl_vat"])
print(slim.shape, lines.shape)
(71, 10) (71, 12)
drop mengembalikan frame baru. errors="ignore" membuatnya tidak protes kalau sebuah kolom tidak ada. Memilih kolom yang mau kamu simpan (lines[[...]]) sering lebih jelas daripada menulis daftar yang mau dibuang, karena bentuk hasilnya terlihat langsung di kode.
Mengurutkan ulang kolom
Urutan kolom lebih penting daripada kelihatannya. Orang yang membaca tabelmu melihat kolom-kolom di sebelah kiri lebih dulu, jadi yang paling penting (id pesanan, produk, revenue) sebaiknya di depan. Tidak ada method khusus untuk mengurutkan ulang; kamu cukup memilih kolom-kolomnya dalam urutan yang kamu mau:
first = ["order_id", "product", "revenue"]
ordered = lines[first + [c for c in lines.columns if c not in first]]
print(list(ordered.columns)[:5])
['order_id', 'product', 'revenue', 'category', 'quantity']
Mengapa ini penting untuk kode yang bersih
Beri kolom turunan nama yang menyatakan dengan tepat isinya (revenue_incl_vat, bukan rev2), standarkan nama kolom sekali saat memuat data, dan utamakan assign saat kamu ingin setiap langkah menghasilkan hasil baru yang bernama jelas. Hindari mengubah DataFrame bersama secara diam-diam dari beberapa tempat: saat sebuah kolom muncul "entah dari mana", pembaca berikutnya harus mencari di mana kolom itu dibuat.
Rangkuman
df["new"] = expressionmenambahkan kolom; perhitungan tervektorisasi berjalan pada seluruh kolom.np.where(cond, a, b)untuk pilihan dua arah;pd.cut(col, bins, labels)untuk rentang;.map(dict)untuk pencarian nilai.df.assign(name=value_or_lambda)mengembalikan frame baru; lambda bisa melihat kolom yang dibuat sebelumnya di pemanggilan yang sama.df.rename(columns={old: new}); bersihkan semua nama lewatdf.columns.str....df.drop(columns=[...])mengembalikan frame baru; memilih kolom yang mau disimpan sering lebih jelas.- Urutkan ulang dengan memilih kolom dalam urutan yang kamu mau.