read_csv() adalah pintu masuk data paling umum sekaligus tempat boros yang paling mudah diabaikan: tanpa parameter tambahan, pandas membaca seluruh kolom dan menyimpulkan dtype per kolom. Pada file transaksi 120.000 baris, pola baca polos memakan 8.713.123 byte — padahal pekerjaan nyata biasanya hanya memakai sebagian kolom dan nilai yang muat di dtype kecil. Chapter ini merapikan empat parameter penghemat (usecols, dtype, nrows, skiprows) serta pilihan mesin engine, lengkap dengan jebakan yang sering menimpa parameter terakhir.

Empat Parameter Penghemat #

Skrip berikut tetap memakai file CSV 120.000 baris yang dibangun runtime dari seed tetap, lalu mengukur dampak tiap parameter dengan memory_usage(deep=True):

python
import shutil
import tempfile
from pathlib import Path

import numpy as np
import pandas as pd

# File CSV 120.000 baris, dibangun runtime secara deterministik
rng = np.random.default_rng(42)
n = 120_000
df = pd.DataFrame(
    {
        "id_pesanan": [f"TRX-{i:06d}" for i in range(n)],
        "kota": rng.choice(["Jakarta", "Bandung", "Surabaya", "Medan", "Semarang"], size=n),
        "produk": rng.choice(
            ["Beras", "Minyak Goreng", "Gula Pasir", "Kopi", "Telur", "Tepung Terigu", "Sabun", "Sarden"],
            size=n,
        ),
        "jumlah": rng.integers(1, 11, size=n),
        "harga": rng.choice([15000, 25000, 40000, 55000, 70000], size=n),
    }
)
df["total"] = df["jumlah"] * df["harga"]
folder = tempfile.mkdtemp()
jalur = Path(folder) / "transaksi.csv"
df.to_csv(jalur, index=False)
print("file:", f"{jalur.stat().st_size:,}", "byte")
print()

# 1. Baca polos: semua kolom, dtype bawaan
dasar = pd.read_csv(jalur)
print("dtypes dasar:", dasar.dtypes.astype(str).to_dict())
print("memori dasar :", f"{int(dasar.memory_usage(deep=True).sum()):,}", "byte")
print()

# 2. usecols: baca kolom yang benar-benar dipakai saja
sedikit = pd.read_csv(jalur, usecols=["kota", "jumlah", "total"])
print("usecols kolom:", list(sedikit.columns))
print("memori usecols:", f"{int(sedikit.memory_usage(deep=True).sum()):,}", "byte")
print()

# 3. dtype eksplisit: kecilkan saat membaca, bukan sesudah
tipis = pd.read_csv(
    jalur,
    usecols=["kota", "jumlah", "total"],
    dtype={"jumlah": "int8", "kota": "category"},
)
print("dtypes tipis:", tipis.dtypes.astype(str).to_dict())
print("memori tipis :", f"{int(tipis.memory_usage(deep=True).sum()):,}", "byte")
print("rasio:", round(int(dasar.memory_usage(deep=True).sum()) / int(tipis.memory_usage(deep=True).sum()), 1))
print()

# 4. nrows: pratinjau murah sebelum membaca semua
pratinjau = pd.read_csv(jalur, nrows=5)
print("nrows=5 shape:", pratinjau.shape)
print()

# 5. Gotcha skiprows: header ikut terlewati bila salah hitung
salah = pd.read_csv(jalur, skiprows=1)
print("skiprows=1 header:", list(salah.columns)[:3])
print("skiprows=1 shape:", salah.shape)
print()

# 6. engine pyarrow: dtype identik, fitur chunksize/nrows tidak didukung
pa = pd.read_csv(jalur, engine="pyarrow", usecols=["kota", "jumlah", "total"])
print("pyarrow dtypes:", pa.dtypes.astype(str).to_dict())
print("pyarrow dtypes == engine c:", pa.dtypes.equals(dasar[["kota", "jumlah", "total"]].dtypes))
try:
    pd.read_csv(jalur, engine="pyarrow", chunksize=30_000)
except ValueError as e:
    print("pyarrow + chunksize ->", str(e).splitlines()[0])

shutil.rmtree(folder)
print("file csv sementara dihapus")

Output yang Dihasilkan:

text
file: 5,093,605 byte

dtypes dasar: {'id_pesanan': 'str', 'kota': 'str', 'produk': 'str', 'jumlah': 'int64', 'harga': 'int64', 'total': 'int64'}
memori dasar : 8,713,123 byte

usecols kolom: ['kota', 'jumlah', 'total']
memori usecols: 3,719,184 byte

dtypes tipis: {'kota': 'category', 'jumlah': 'int8', 'total': 'int64'}
memori tipis : 1,200,380 byte
rasio: 7.3

nrows=5 shape: (5, 6)

skiprows=1 header: ['TRX-000000', 'Jakarta', 'Beras']
skiprows=1 shape: (119999, 6)

pyarrow dtypes: {'kota': 'str', 'jumlah': 'int64', 'total': 'int64'}
pyarrow dtypes == engine c: True
pyarrow + chunksize -> The 'chunksize' option is not supported with the 'pyarrow' engine
file csv sementara dihapus

Mari kita telaah baris-baris pentingnya:

  1. Baris 31-33 (baca polos): tiga kolom teks memakai dtype str bawaan pandas 3.0 dan tiga kolom angka memakai int64; totalnya 8.713.123 byte. Inilah garis dasar yang akan kita tekan.
  2. Baris 37-39 (usecols): hanya tiga kolom yang benar-benar dipakai (kota, jumlah, total) yang dibaca — memori turun menjadi 3.719.184 byte. Kolom yang tidak disebut tidak pernah masuk memori; inilah penghematan termurah.
  3. Baris 43-50 (dtype eksplisit): dtype ditetapkan saat membaca — jumlah langsung int8 dan kota langsung category, tanpa langkah astype sesudahnya. Memori jatuh ke 1.200.380 byte, rasio 7.3 dibanding baca polos, dengan hanya tiga kolom yang dipakai.
  4. Baris 54-55 (nrows=5): pratinjau lima baris pertama untuk memeriksa struktur file sebelum membaca semuanya — murah, cepat, dan wajib dilakukan pada file asing.
  5. Baris 59-61 (jebakan skiprows): skiprows=1 melewatkan baris pertama FILE, termasuk baris header-nya, sehingga data pertama (TRX-000000) menjadi nama kolom dan jumlah baris tersisa 119.999. Untuk melewati baris di atas header, skiprows tetap tepat; untuk melewati baris data, gunakan nrows atau filter sesudahnya.
  6. Baris 64-71 (engine="pyarrow"): mesin pyarrow menghasilkan dtype yang identik dengan mesin "c" bawaan (str dan int64), jadi hasilnya kompatibel; mesin ini mengurai CSV di sisi Arrow dan umumnya lebih cepat pada file besar. Namun dua fitur tidak didukungnya — percobaan chunksize memunculkan ValueError: The 'chunksize' option is not supported with the 'pyarrow' engine — sehingga pola chunking Chapter sebelumnya tetap memerlukan mesin "c".

Ringkasan Parameter #

ParameterEfekKapan dipakai
usecols=[...]hanya kolom yang disebut yang dibacahampir selalu
dtype={...}tetapkan dtype saat parsingkolom angka kecil, teks berulang
nrows=nbatasi jumlah barispratinjau file asing
skiprows=nlewati baris awal filemetadata/komentar di atas header
engine="pyarrow"mesin parsing Arrowfile besar, tanpa chunksize/nrows

Sampai di sini, data besar sudah bisa masuk dengan hemat dan keluar dengan cepat. Chapter berikutnya membahas hal yang bekerja di balik semua penghematan itu: perilaku Copy-on-Write pandas 3.0 — kapan pandas menyalin, kapan hanya melihat, dan apa dampaknya pada performa.

Referensi resmi untuk pendalaman: pandas.read_csv , panduan IO tools , dan catatan rilis pandas 3.0.0 .