Saya mencari cara cepat untuk mempertahankan array numpy yang besar. Saya ingin menyimpannya ke disk dalam format biner, lalu membacanya kembali ke memori dengan relatif cepat. Sayangnya, cPickle tidak cukup cepat.
Saya menemukan numpy.savez dan numpy.load . Namun yang aneh adalah, numpy.load memuat file npy ke dalam "memory-map". Itu berarti manipulasi array secara teratur sangat lambat. Misalnya, sesuatu seperti ini akan sangat lambat:
#!/usr/bin/python
import numpy as np;
import time;
from tempfile import TemporaryFile
n = 10000000;
a = np.arange(n)
b = np.arange(n) * 10
c = np.arange(n) * -0.5
file = TemporaryFile()
np.savez(file,a = a, b = b, c = c);
file.seek(0)
t = time.time()
z = np.load(file)
print "loading time = ", time.time() - t
t = time.time()
aa = z['a']
bb = z['b']
cc = z['c']
print "assigning time = ", time.time() - t;
lebih tepatnya, baris pertama akan sangat cepat, tetapi baris lainnya yang menetapkan array obj
sangat lambat:
loading time = 0.000220775604248
assining time = 2.72940087318
Apakah ada cara yang lebih baik untuk mengawetkan array numpy? Idealnya, saya ingin bisa menyimpan banyak array dalam satu file.
np.load
sebaiknya tidak mmap file.numpy.savez
), defaultnya adalah "memuat dengan malas" array. Ini tidak memetakannya, tetapi tidak memuatnya sampaiNpzFile
objek diindeks. (Jadi penundaan yang dimaksud OP.) Dokumentasi untukload
melewatkan ini, dan oleh karena itu sedikit menyesatkan ...Jawaban:
Saya penggemar berat hdf5 karena menyimpan array numpy yang besar. Ada dua opsi untuk menangani hdf5 dengan python:
http://www.pytables.org/
http://www.h5py.org/
Keduanya dirancang untuk bekerja dengan array numpy secara efisien.
sumber
Saya telah membandingkan kinerja (ruang dan waktu) untuk sejumlah cara menyimpan array numpy. Beberapa dari mereka mendukung banyak larik per file, tetapi mungkin itu berguna.
File npy dan binary keduanya sangat cepat dan kecil untuk data yang padat. Jika datanya jarang atau sangat terstruktur, Anda mungkin ingin menggunakan npz dengan kompresi, yang akan menghemat banyak ruang tetapi membutuhkan waktu muat.
Jika portabilitas menjadi masalah, biner lebih baik daripada npy. Jika keterbacaan manusia itu penting, maka Anda harus mengorbankan banyak kinerja, tetapi itu dapat dicapai dengan cukup baik menggunakan csv (yang juga sangat portabel tentunya).
Detail lebih lanjut dan kodenya tersedia di repo github .
sumber
binary
lebih baik daripadanpy
portabilitas? Apakah ini juga berlakunpz
?Sekarang ada tiruan berbasis HDF5 yang
pickle
disebuthickle
!https://github.com/telegraphic/hickle
EDIT:
Ada juga kemungkinan untuk "mengawetkan" langsung ke dalam arsip terkompresi dengan melakukan:
Lampiran
sumber
savez () menyimpan data dalam file zip, Mungkin perlu beberapa saat untuk membuat zip & mengekstrak file. Anda dapat menggunakan fungsi save () & load ():
Untuk menyimpan beberapa array dalam satu file, Anda hanya perlu membuka file terlebih dahulu, lalu menyimpan atau memuat array secara berurutan.
sumber
Kemungkinan lain untuk menyimpan array numpy secara efisien adalah Bloscpack :
dan output untuk laptop saya (MacBook Air yang relatif lama dengan prosesor Core2):
itu berarti dapat menyimpan dengan sangat cepat, yaitu kemacetan biasanya adalah disk. Namun, karena rasio kompresinya cukup bagus di sini, kecepatan efektif dikalikan dengan rasio kompresi. Berikut adalah ukuran untuk array 76 MB ini:
Harap dicatat bahwa penggunaan kompresor Blosc sangat penting untuk mencapai hal ini. Skrip yang sama tetapi menggunakan 'clevel' = 0 (yaitu menonaktifkan kompresi):
jelas terhambat oleh kinerja disk.
sumber
Waktu pencarian lambat karena saat Anda menggunakan
mmap
untuk tidak memuat konten larik ke memori saat Anda memanggilload
metode. Data dimuat lambat saat data tertentu diperlukan. Dan ini terjadi dalam pencarian dalam kasus Anda. Tapi pencarian kedua tidak akan terlalu lambat.Ini adalah fitur yang bagus dari
mmap
ketika Anda memiliki array yang besar Anda tidak perlu memuat seluruh data ke dalam memori.Untuk menyelesaikannya, Anda dapat menggunakan joblib, Anda dapat membuang objek apa pun yang Anda inginkan menggunakan
joblib.dump
dua atau lebihnumpy arrays
, lihat contohsumber