Memilih dtype bukan hanya soal kebenaran hitungan, tetapi juga keputusan performa: dtype menentukan itemsize, dan itemsize menentukan nbytes seluruh array. Tipe yang terlalu besar memboroskan memori dan bandwidth; tipe yang terlalu kecil memangkas biaya tetapi menuntut kompromi jangkauan atau presisi.

Bab ini menyusun pedoman praktisnya: batas tiap tipe, perbandingan kebutuhan memori per juta elemen, kasus khas data 0-255, serta kapan float32 cukup dan kapan harus mundur ke float64.

Jangkauan dan Batas Tiap Tipe #

Modul NumPy menyediakan inspektur bawaan: np.iinfo untuk tipe bulat dan np.finfo untuk tipe float. Keduanya mengembalikan nilai yang deterministik, sehingga layak dijadikan blok uji:

python
import numpy as np

print("int8 :", np.iinfo(np.int8).min, "sampai", np.iinfo(np.int8).max)
print("uint8:", np.iinfo(np.uint8).min, "sampai", np.iinfo(np.uint8).max)
print("int32:", np.iinfo(np.int32).min, "sampai", np.iinfo(np.int32).max)
print("eps float32:", np.finfo(np.float32).eps)
print("eps float64:", np.finfo(np.float64).eps)

Output yang Dihasilkan:

text
int8 : -128 sampai 127
uint8: 0 sampai 255
int32: -2147483648 sampai 2147483647
eps float32: 1.1920929e-07
eps float64: 2.220446049250313e-16

Cara membacanya:

  1. Baris 3-5 (np.iinfo(...)): atribut min dan max menunjukkan jangkauan aman tiap tipe bulat; nilai di luar batas ini memicu overflow.
  2. Baris 6-7 (np.finfo(...).eps): eps adalah jarak antara 1.0 dan nilai float terdekat yang masih bisa dibedakan — sekitar 1e-07 untuk float32 dan 2e-16 untuk float64. Selisih tujuh tingkat besaran inilah ukuran presisi yang kita taruhkan.
TipeItemsizeJangkauan intiKhas untuk
int8 / uint81 byte-128..127 / 0..255label kelas, piksel
int32 / uint324 byte±2,1 miliarID, jumlah baris menengah
int648 byte±9,2 x 10^18indeks bawaan NumPy
float324 bytepresisi ~7 digitfitur machine learning, grafis
float648 bytepresisi ~16 digitperhitungan ilmiah default

Matematika Memori per Juta Elemen #

Dengan itemsize di tangan, kebutuhan memori bisa dihitung sebelum data dibuat. Baris berikut mengalokasikan satu juta elemen pada lima dtype dan melaporkan nbytes:

python
import numpy as np

n = 1_000_000
for nama in ("float64", "float32", "int64", "int32", "uint8"):
    a = np.zeros(n, dtype=nama)
    print(f"{nama:8s} -> {a.nbytes:>9,} byte")

Output yang Dihasilkan:

text
float64  -> 8,000,000 byte
float32  -> 4,000,000 byte
int64    -> 8,000,000 byte
int32    -> 4,000,000 byte
uint8    -> 1,000,000 byte
  1. Baris 4-5: loop mencoba lima dtype pada jumlah elemen yang sama, sehingga satu-satunya variabel adalah itemsize.
  2. Baris 6 (a.nbytes): hasilnya selalu n x itemsize: delapan juta untuk tipe 8 byte, empat juta untuk 4 byte, dan satu juta untuk uint8.

Skalanya berlaku linear: dataset seratus juta elemen float64 memakai 800 MB, sementara float32 cukup 400 MB — selisih yang menentukan apakah data muat di RAM mesin kerja.

uint8 untuk Data 0-255 #

Banyak data nyata yang jangkauannya alami 0-255: intensitas piksel grayscale, label kelas, nilai kuesioner. Menyimpannya sebagai float64 berarti memakai delapan kali kebutuhan sebenarnya:

python
import numpy as np

piksel = np.array([200, 150, 0, 255, 128], dtype=np.uint8)
print("dtype uint8 :", piksel.nbytes, "byte")
sebagai_float = piksel.astype(np.float64)
print("dtype float64:", sebagai_float.nbytes, "byte")

Output yang Dihasilkan:

text
dtype uint8 : 5 byte
dtype float64: 40 byte
  1. Baris 3 (dtype=np.uint8): lima nilai muat persis di jangkauan 0-255, maka 5 byte sudah cukup.
  2. Baris 5 (astype): konversi ke float64 menaikkan konsumsi menjadi 40 byte tanpa menambah informasi sedikit pun.

Pola ini penting saat memuat gambar: citra 4000x3000 grayscale memakai 12 MB sebagai uint8 tetapi 96 MB sebagai float64 — perbandingan lengkapnya ada pada Chapter NumPy untuk Pemrosesan Gambar.

Kapan float32 Cukup #

Aturan singkatnya: float32 cukup bila nilai berada pada rentang wajar dan hasil tidak membutuhkan lebih dari ±7 digit signifikan. Kelemahannya paling terlihat saat menjumlahkan angka kecil ke akumulasi yang besar:

python
import numpy as np

x32 = np.array([1e8, 1, 1], dtype=np.float32)
x64 = np.array([1e8, 1, 1], dtype=np.float64)
print("float32:", x32.sum())
print("float64:", x64.sum())

Output yang Dihasilkan:

text
float32: 100000000.0
float64: 100000002.0

Cara membacanya:

  1. Baris 3-4: data yang sama disimpan dalam dua presisi; angka 100 juta masih dalam jangkauan keduanya.
  2. Baris 5-6: pada float32, jarak antar nilai float di sekitar 100 juta sudah sekitar 8, sehingga tambahan 1 dan 1 tenggelam dan totalnya tidak berubah. float64 menghasilkan 100000002.0 dengan benar.

Pedoman pilihan cepat:

  1. Label kelas dan piksel: uint8 atau int32 — hemat dan presisi penuh.
  2. Fitur machine learning berskala besar: float32 — pustaka seperti scikit-learn dan framework deep learning terbiasa dengannya.
  3. Perhitungan ilmiah, uang, akumulasi panjang: float64, atau bahkan tipe bulat untuk uang.
  4. Ragu antara dua tipe: hitung selisih nbytes, lalu uji akurasi hasil pada sampel data sebelum memutuskan.