Berkas data modern mudah melampaui memori kerja komputer: rekaman sensor berbulan-bulan, dataset citra, atau hasil simulasi berukuran gigabyte. Pendekatan biasa — np.fromfile atau np.load — memuat seluruh berkas ke RAM sebelum satu nilai pun bisa dipakai. NumPy menyediakan jalan lain: memory-mapped array, array yang isinya dipetakan langsung ke berkas di disk, sehingga sistem operasi hanya membaca bagian yang benar-benar diakses.
Konstruktor np.memmap menghasilkan ndarray biasa dari sisi pemakaian — diindeks, di-slice, dijumlahkan — tetapi penyimpanannya berada di berkas, bukan di RAM penuh. Bab ini membahas empat mode pembukaannya beserta pola penulisan yang aman.
Membuat dan Membaca memmap #
np.memmap membutuhkan dtype dan shape secara eksplisit, karena berkas biner mentah tidak menyimpan metadata. Mode w+ membuat berkas baru (atau mengosongkan yang ada); setelah diisi, berkas yang sama dapat dibuka dari proses atau sesi lain dengan mode r:
import numpy as np
m = np.memmap("besar.bin", dtype=np.float64, mode="w+", shape=(4, 3))
m[:] = np.arange(12, dtype=np.float64).reshape(4, 3)
m.flush()
print(m.shape, m.dtype)
r = np.memmap("besar.bin", dtype=np.float64, mode="r", shape=(4, 3))
print(r[0])
print(r[:, 0])Output yang Dihasilkan:
(4, 3) float64
[0. 1. 2.]
[0. 3. 6. 9.]Mari kita bedah:
- Baris 3 (
mode="w+", shape=(4, 3)): berkas 96 byte disiapkan (12 × 8 byte); shape dan dtype wajib disebut karena tidak ada header yang menyimpannya. - Baris 4-5 (
m[:] = ...; m.flush()): pengisian dilakukan lewat slice penuh, laluflush()memaksa isi memori dituliskan ke berkas. - Baris 7-9: pembukaan kedua memakai mode
r(hanya baca); indexing dan slicing berjalan seperti array biasa, danr[:, 0]membaca kolom pertama tanpa menyalin seluruh berkas ke array.
Menulis Perubahan dengan r+ dan flush #
Mode r+ membuka berkas yang sudah ada untuk dibaca dan ditulis. Perubahan pada memmap bekerja seperti array biasa, tetapi hanya menjadi permanen di berkas setelah flush() dipanggil:
import numpy as np
np.arange(100, 106, dtype=np.int32).tofile("log.bin")
m = np.memmap("log.bin", dtype=np.int32, mode="r+", shape=(6,))
m[0] = 999
m.flush()
print(np.fromfile("log.bin", dtype=np.int32))Output yang Dihasilkan:
[999 101 102 103 104 105]Penjelasan tiap bagian:
- Baris 3 (
tofile(...)): berkas berisi[100 101 102 103 104 105]disiapkan sebagai bahan uji. - Baris 4-5 (
mode="r+"): elemen pertama diubah menjadi999lewat memmap; operasi penugasan ini sama persis dengan array biasa. - Baris 6-7: setelah
flush(), pembacaan ulang lewat jalur terpisah (np.fromfile) membuktikan nilai baru benar-benar tertulis ke berkas — tanpaflush(), perubahan masih mengendap di memori.
Mode c: Perubahan yang Tidak Tertulis #
Mode c (copy-on-write) adalah mode ketiga: array bisa diubah di memori, tetapi setiap perubahan tidak pernah sampai ke berkas. Berguna ketika kita ingin bereksperimen pada data tanpa merusak sumbernya:
import numpy as np
np.arange(100, 106, dtype=np.int32).tofile("log.bin")
c = np.memmap("log.bin", dtype=np.int32, mode="c", shape=(6,))
c[1] = -1
print(c)
print(np.fromfile("log.bin", dtype=np.int32))Output yang Dihasilkan:
[100 -1 102 103 104 105]
[100 101 102 103 104 105]Mari kita telaah:
- Baris 3-4 (
mode="c"): elemen kedua diubah menjadi-1dan terlihat berubah pada cetakan pertama. - Baris 5-6: pembacaan berkas yang sama memperlihatkan isi asli
[100 101 102 103 104 105]— perubahan hanya hidup di memori proses tersebut. - Perbandingan dengan bagian sebelumnya menegaskan perannya:
r+menulis permanen setelahflush,ctidak pernah menulis.
offset: Memetakan Sebagian Berkas #
Parameter offset memetakan berkas mulai dari byte ke-N, sehingga satu berkas besar dapat dipotong-potong menjadi beberapa tampilan tanpa memuat sisanya. Nilai offset harus kelipatan ukuran satu elemen:
import numpy as np
np.arange(100, 106, dtype=np.int32).tofile("log.bin")
p = np.memmap("log.bin", dtype=np.int32, mode="r", offset=4, shape=(5,))
print(p)Output yang Dihasilkan:
[101 102 103 104 105]Penjelasan tiap bagian:
- Baris 3 (
offset=4): pemetaan dimulai pada byte keempat, yaitu tepat setelah elemenint32pertama. - Baris 3 (
shape=(5,)): dari titik itu, hanya lima elemen sisanya yang dipetakan. - Baris keluaran: hasilnya
[101 102 103 104 105]— elemen pertama berkas tidak pernah disentuh.
| Mode | Baca | Tulis | Perubahan ke berkas |
|---|---|---|---|
r | ya | tidak | tidak ada penulisan sama sekali |
r+ | ya | ya | permanen setelah flush() |
c | ya | ya | hanya di memori, berkas tetap asli |
w+ | ya | ya | berkas baru dibuat lalu diisi |