Keuntungan dtype category selama ini kita uji pada data kecil; pada data jutaan baris, penghematannya terasa nyata. Kolom str menyimpan teks utuh di setiap baris, sedangkan kolom category menyimpan satu daftar kategori plus kode integer per baris — biayanya turun drastis ketika jumlah kategori jauh lebih kecil daripada jumlah baris. Chapter ini mengukur perbandingannya dengan memory_usage(deep=True) pada 100.000 baris, memangkas DataFrame utuh sekaligus, lalu merangkum kapan konversi ini tepat dan kapan sebaiknya ditunda.

Mengukur Memori Satu Kolom #

python
import pandas as pd
import numpy as np

n = 100_000
kota = np.repeat(["Jakarta", "Bandung", "Surabaya", "Medan", "Semarang"], n // 5)
teks = pd.Series(kota)
print(teks.dtype)

mem_str = teks.memory_usage(deep=True)
print(mem_str)

kategori = teks.astype("category")
mem_cat = kategori.memory_usage(deep=True)
print(mem_cat)
print(round(mem_str / mem_cat, 1))
print(kategori.cat.codes.dtype)

df = pd.DataFrame({
    "kota": teks,
    "status": np.repeat(["member", "reguler"], n // 2),
})
mem_sebelum = df.memory_usage(deep=True).sum()
df["kota"] = df["kota"].astype("category")
df["status"] = df["status"].astype("category")
mem_sesudah = df.memory_usage(deep=True).sum()
print(mem_sebelum, mem_sesudah, round(mem_sebelum / mem_sesudah, 1))

Output yang Dihasilkan:

text
str
1500132
100208
15.0
int8
2950132 200238 14.7

Mari kita telaah bagian penting skrip di atas:

  1. Baris 4-7: np.repeat menyusun 100.000 baris dari lima nama kota, 20.000 baris per kota; dtype kolomnya str.
  2. Baris 9-10: memory_usage(deep=True) menghitung memori sebenarnya termasuk isi string — kolom str memakai 1.500.132 byte.
  3. Baris 12-14: astype("category") mengubah kolom menjadi 100.208 byte, kira-kira seratus kilobyte.
  4. Baris 15-16: rasio keduanya 15.0, dan .cat.codes mengonfirmasi kode per baris bertipe int8 — satu byte per baris.

Angka-angka itu masuk akal bila diuraikan: versi str menyimpan rata-rata lima belas byte teks per baris, sementara versi category menyimpan satu byte kode per baris ditambah daftar lima kategori yang hanya dihitung sekali. Perbandingan ini juga menjadi cara memeriksa prasyarat konversi: karena lima kategori jauh lebih kecil daripada 100.000 baris, category jelas menguntungkan.

Memangkas DataFrame Utuh #

Baris 18-26 mengulang pengukuran pada DataFrame dua kolom, kota dan status. Sebelum konversi, df.memory_usage(deep=True).sum() melaporkan 2.950.132 byte; setelah kedua kolom dikonversi, totalnya tinggal 200.238 byte — rasio 14.7. memory_usage(deep=True) mengembalikan Series per kolom termasuk index, sehingga .sum() memberi total yang bisa Anda bandingkan sebelum dan sesudah perubahan struktur data.

Kapan category Tepat Digunakan #

Kondisi kolomRekomendasi
Sedikit nilai unik, banyak bariscategory menguntungkan, hemat belasan kali
Nilai unik mendekati jumlah bariscategory justru lebih boros; pertahankan str
Kolom butuh operasi teks .str intensifkerjakan .str dulu, konversi di akhir
Kolom perlu nilai baru sewaktu-waktusiapkan add_categories() dari chapter sebelumnya

Kondisi kedua patut dijaga: konversi kolom ID unik seperti email per baris ke category malah menambah biaya, karena daftar kategorinya sepanjang data itu sendiri. Kebiasaan yang sehat adalah mengukur dulu dengan memory_usage(deep=True), mengonversi kolom berulang saja, lalu mencatat perubahan rasionya.

Dokumentasi resmi yang relevan: User Guide: Categorical data , pandas.DataFrame.memory_usage , dan pandas.Categorical .

Section Data Teks dan Kategori kini tuntas: .str mengolah teks per baris, CategoricalDtype memberi makna pada nilai berulang, dan kategori memangkas memori. Data nyata berikutnya tidak selalu rapi — banyak baris kosong dan nilai menyimpang menunggu, dan itu menjadi pembuka Section Missing Data dan Outlier Lanjutan pada chapter Pola Missing Data.