Szukam szybkiego sposobu na zachowanie dużych, zdrętwiałych tablic. Chcę je zapisać na dysku w formacie binarnym, a następnie stosunkowo szybko wczytać z powrotem do pamięci. Niestety, cPickle nie jest wystarczająco szybki.
Znalazłem numpy.savez i numpy.load . Ale dziwne jest to, że numpy.load ładuje plik npy do "mapy pamięci". Oznacza to, że regularne manipulowanie tablicami jest naprawdę powolne. Na przykład coś takiego byłoby naprawdę powolne:
#!/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;
dokładniej, pierwsza linia będzie naprawdę szybka, ale pozostałe linie, które przypisują tablice, obj
są absurdalnie wolne:
loading time = 0.000220775604248
assining time = 2.72940087318
Czy jest lepszy sposób na zachowanie tablic numpy? W idealnym przypadku chciałbym mieć możliwość przechowywania wielu tablic w jednym pliku.
np.load
należy mmapować pliku.numpy.savez
), domyślnie tablice są ładowane leniwie. Nie jest to memmapowanie ich, ale nie ładuje ich, dopókiNpzFile
obiekt nie zostanie zindeksowany. (Stąd opóźnienie, do którego odnosi się PO.) Dokumentacjaload
pomija to i dlatego jest trochę myląca ...Odpowiedzi:
Jestem wielkim fanem hdf5 do przechowywania dużych tablic numpy. Istnieją dwie możliwości radzenia sobie z hdf5 w Pythonie:
http://www.pytables.org/
http://www.h5py.org/
Oba są zaprojektowane do wydajnej pracy z tablicami numpy.
źródło
Porównałem wydajność (przestrzeń i czas) dla wielu sposobów przechowywania tablic numpy. Niewiele z nich obsługuje wiele tablic na plik, ale być może i tak jest to przydatne.
Pliki Npy i binarne są bardzo szybkie i małe dla gęstych danych. Jeśli dane są rzadkie lub bardzo uporządkowane, możesz chcieć użyć npz z kompresją, co pozwoli zaoszczędzić dużo miejsca, ale kosztuje trochę czasu ładowania.
Jeśli problemem jest przenośność, plik binarny jest lepszy niż npy. Jeśli czytelność dla ludzi jest ważna, będziesz musiał poświęcić dużo wydajności, ale można to całkiem dobrze osiągnąć za pomocą csv (który jest oczywiście również bardzo przenośny).
Więcej szczegółów i kod są dostępne w repozytorium github .
źródło
binary
jest lepsze niż wnpy
przypadku przenośności? Czy to dotyczy równieżnpz
?Jest teraz oparty na HDF5 klon
pickle
nazwanyhickle
!https://github.com/telegraphic/hickle
EDYTOWAĆ:
Istnieje również możliwość "wytrawiania" bezpośrednio do skompresowanego archiwum, wykonując:
dodatek
źródło
savez () zapisuje dane w pliku zip, skompresowanie i rozpakowanie pliku może zająć trochę czasu. Możesz użyć funkcji save () & load ():
Aby zapisać wiele tablic w jednym pliku, wystarczy najpierw otworzyć plik, a następnie zapisać lub załadować tablice po kolei.
źródło
Inną możliwością efektywnego przechowywania tablic numpy jest Bloscpack :
i wyjście dla mojego laptopa (stosunkowo stary MacBook Air z procesorem Core2):
oznacza to, że może przechowywać naprawdę szybko, tj. wąskim gardłem jest zwykle dysk. Ponieważ jednak współczynniki kompresji są tutaj całkiem dobre, efektywna prędkość jest mnożona przez współczynniki kompresji. Oto rozmiary tych 76 MB macierzy:
Należy pamiętać, że użycie kompresora Blosc jest podstawą do osiągnięcia tego. Ten sam skrypt, ale używający „clevel” = 0 (tj. Wyłączając kompresję):
jest wyraźnie ograniczony przez wydajność dysku.
źródło
Czas wyszukiwania jest długi, ponieważ gdy używasz
mmap
do, nie ładuje zawartości tablicy do pamięci podczas wywoływaniaload
metody. Dane są ładowane z opóźnieniem, gdy potrzebne są określone dane. Dzieje się to podczas wyszukiwania w Twoim przypadku. Ale drugie wyszukiwanie nie będzie tak powolne.Jest to fajna cecha,
mmap
gdy masz dużą tablicę, nie musisz ładować całych danych do pamięci.Aby rozwiązać problem, użyj joblib , możesz zrzucić dowolny obiekt, używając
joblib.dump
nawet dwóch lub więcejnumpy arrays
, patrz przykładźródło