Teknik hemat memori pada Section ini punya batas yang tetap: pandas bekerja di satu mesin dan memuat seluruh DataFrame ke RAM. Kita bisa menekan konsumsi beberapa kali lipat dengan downcast dan category, tetapi angka dasarnya tumbuh linear terhadap jumlah baris dan kolom. Chapter ini memberi kerangka untuk memutuskan kapan pandas masih tepat: mengukur harga memori per kolom, mengestimasi kebutuhan tabel utuh, lalu membandingkannya dengan anggaran RAM. Setelah batasnya terlihat jelas, kita tinjau pilihan berikutnya — pola chunk, format kolom, hingga DuckDB, Polars, dan PySpark — secara konseptual, tanpa mengganti peralatan di tengah course.

Memori Mesin Tunggal sebagai Batas Utama #

Pandas menyimpan setiap kolom sebagai satu blok array di RAM, sehingga seluruh tabel harus muat sekaligus di memori. Tidak ada mode out-of-core bawaan: ketika read_csv() menemukan file jauh lebih besar dari RAM, prosesnya berhenti dengan MemoryError. Karena itu keputusan memakai pandas pada data besar bukan soal selera, melainkan soal perkalian sederhana: jumlah baris × jumlah kolom × byte per nilai. Model ini sengaja disederhanakan — kolom str dan category berharga sendiri-sendiri — tetapi cukup untuk memutuskan arah: int64 dan float64 8 byte per nilai, int32 4 byte, int8 1 byte.

Mengukur Batas dengan Kode #

Skrip berikut mengukur harga nyata satu kolom, estimasi linear tabel utuh pada tiga skala, dan hasil teknik Section ini pada tabel satu juta baris:

python
import numpy as np
import pandas as pd

# 1. Harga memori satu kolom, terukur nyata
kolom = pd.Series(np.arange(1_000_000, dtype="int64"))
byte_kolom = int(kolom.memory_usage(deep=True)) - 132  # index RangeIndex = 132 byte
print("1.000.000 baris int64 :", f"{byte_kolom:,}", "byte")
print("per baris             :", byte_kolom // 1_000_000, "byte")
print()

# 2. Estimasi linear: baris x kolom x byte per baris
def estimasi_memori(jumlah_baris, jumlah_kolom, byte_per_baris=8):
    return jumlah_baris * jumlah_kolom * byte_per_baris


anggaran_ram = 8_000_000_000  # RAM laptop 8 GB
for baris, kol in [(10_000_000, 20), (50_000_000, 20), (100_000_000, 20)]:
    butuh = estimasi_memori(baris, kol)
    print(f"{baris:>13,} baris x {kol} kolom int64 = {butuh // 1_000_000:>6,} MB | muat 8 GB: {butuh < anggaran_ram}")
print()

# 3. Teknik Section ini diukur pada 1.000.000 baris
rng = np.random.default_rng(42)
df = pd.DataFrame(
    {
        "kota": rng.choice(["Jakarta", "Bandung", "Surabaya", "Medan", "Semarang"], size=1_000_000),
        "jumlah": rng.integers(1, 11, size=1_000_000),
        "harga": rng.choice([15000, 25000, 40000, 55000, 70000], size=1_000_000),
    }
)
df["total"] = df["jumlah"] * df["harga"]
awal = int(df.memory_usage(deep=True).sum())

df_hemat = df.copy()
df_hemat["kota"] = df_hemat["kota"].astype("category")
df_hemat["jumlah"] = pd.to_numeric(df_hemat["jumlah"], downcast="integer")
df_hemat["harga"] = pd.to_numeric(df_hemat["harga"], downcast="integer")
df_hemat["total"] = pd.to_numeric(df_hemat["total"], downcast="integer")
akhir = int(df_hemat.memory_usage(deep=True).sum())

print("1 jt baris, 4 kolom, baca polos :", f"{awal:,}", "byte")
print("setelah category + downcast     :", f"{akhir:,}", "byte")
print("rasio:", round(awal / akhir, 1))
print("nilai total tetap sama:", int(df["total"].sum()) == int(df_hemat["total"].sum()))

Output yang Dihasilkan:

text
1.000.000 baris int64 : 8,000,000 byte
per baris             : 8 byte

   10,000,000 baris x 20 kolom int64 =  1,600 MB | muat 8 GB: True
   50,000,000 baris x 20 kolom int64 =  8,000 MB | muat 8 GB: False
  100,000,000 baris x 20 kolom int64 = 16,000 MB | muat 8 GB: False

1 jt baris, 4 kolom, baca polos : 39,000,029 byte
setelah category + downcast     : 10,000,208 byte
rasio: 3.9
nilai total tetap sama: True

Mari kita telaah baris-baris pentingnya:

  1. Baris 5-8 (harga nyata satu kolom): kolom int64 berisi satu juta baris memakan 8.000.000 byte — index RangeIndex 132 byte dikurangkan — sehingga harganya tepat 8 byte per baris.
  2. Baris 12-19 (estimasi linear): fungsi estimasi_memori() mengalikan baris × kolom × byte per baris. Tabel 20 kolom int64 10 juta baris butuh 1.600 MB dan masih muat di RAM 8 GB; 50 juta baris 8.000 MB — tidak muat; 100 juta baris 16.000 MB — dua kali lipat anggaran.
  3. Baris 23-44 (teknik Section ini pada 1 juta baris): tabel empat kolom memakan 39.000.029 byte saat dibaca polos; setelah category untuk kota dan downcast untuk tiga kolom angka, konsumsinya turun menjadi 10.000.208 byte — rasio 3.9 — dengan total yang tetap sama. Teknik-teknik ini memperluas rentang data yang nyaman, bukan menghapus batasnya: tabel seribu kali lebih besar tetap di luar kemampuan mesin tunggal.

Setelah Batas Tercapai: Pilihan Berikutnya #

SituasiPendekatanCara kerja singkat
Data sedikit melebihi RAMpola chunkproses per potongan dengan chunksize, gabungkan agregasinya di akhir
Kolom yang dipakai sedikitformat kolom (Parquet)simpan sebagai file kolom, baca hanya kolom terpilih; pandas mendukungnya lewat pyarrow
Analisis SQL di atas file besarmesin SQL analitik (DuckDB)kueri SQL langsung ke file CSV/Parquet di disk tanpa memuat seluruhnya
Tabel jauh melebihi satu mesinPolars / PySparkDataFrame API berbasis Arrow dengan eksekusi multi-thread, atau pemrosesan terdistribusi di klaster

Keempat pendekatan itu berbagi satu prinsip: jangan memuat apa pun yang tidak akan diproses. Pola chunk dan format kolom masih di dalam pandas — keduanya sudah kita praktikkan dan sering menunda kebutuhan pindah alat. DuckDB, Polars, dan PySpark adalah lapisan berikutnya dengan sintaks dan ekosistem masing-masing; berpindah ke sana adalah investasi belajar baru — layak hanya setelah estimasi di atas menunjukkan pandas memang tidak sanggup.

Dengan batas pandas yang kini terukur, rangkaian Section ini tuntas: mengukur biaya operasi, mengganti loop dengan operasi vectorized, menekan memori lewat dtype dan category, memproses data per potongan, dan memahami perilaku salinan pandas 3.0. Section berikutnya, Advanced Pandas, dibuka dengan chapter MultiIndex — cara pandas mengelola data bertingkat yang menjadi fondasi sejumlah operasi lanjutan setelahnya.

Referensi resmi untuk pendalaman: panduan Scaling to large datasets , panduan IO tools , dan pandas.read_csv .