2015-02-02 23 views
11

Mam plik npz 3,374 Gb, myfile.npz.Dlaczego ta tablica numpy jest zbyt duża do załadowania?

mogę go odczytać i wyświetlić nazwy plików:

a = np.load('myfile.npz') 
a.files 

daje

['arr_1','arr_0'] 

mogę przeczytać w ok

a1=a['arr_1'] 

Jednak nie można załadować w 'arr_1' arr_0 lub odczytać jego kształt:

a1=a['arr_0'] 
a['arr_0'].shape 

oba powyższe operacje daje następujący błąd:

ValueError: array is too big 

mam 16GB pamięci RAM, która jest dostępna 8.370Gb. Problem nie wydaje się więc związany z pamięcią. Moje pytania to:

  1. Czy mogę przeczytać ten plik?

  2. Czy ktoś może wyjaśnić ten błąd?

  3. Szukałem przy użyciu np.memmap, aby ominąć to - czy jest to rozsądne podejście?

  4. Jakie podejście do debugowania powinienem użyć?

EDIT:

Mam dostęp do komputera z większą ilością pamięci RAM (48GB) i załadowany. Numer dtype był w rzeczywistości complex128, a nieskompresowana pamięć a['arr_0'] wynosiła 5750784000 bajtów. Wygląda na to, że może być potrzebny narzut pamięci RAM. To albo moja przewidywana ilość dostępnej pamięci RAM była zła (użyłem windows sysinternals RAMmap).

+1

podejrzewam przyczynę co możliwe Załadowanie tego jest spowodowane tym, że reprezentacja na przykład 3.4 jako float w pamięci komputera wymaga więcej pamięci niż zapisanie 3.4 na dysku. Ale jestem mniej pewny tego niż ja, zanim zacząłem czytać. – Joel

+0

Czy wiesz, że plik jest skompresowany (został utworzony za pomocą ['np.savez_compressed()'] (http://docs.scipy.org/doc/numpy/reference/generated/numpy.savez_compressed.html#numpy. savez_compressed))? Czy utworzyłeś go na tym samym komputerze, na którym próbujesz go załadować? Czy wiesz, jakie rodzaje tablic zawiera (size i dtype)? –

+0

@ali_m, tak został zapisany z 'np.savez_compressed', ale na innej maszynie. 'Arr_0' jest zmiennoprzecinkowymi (chyba 8 bajtami) o kształcie' (200,1440,3,12,32) ',' arr_1' to (200,3,32) ponownie pływa. – atomh33ls

Odpowiedz

2

np.complex128 tablica o wymiarach (200, 1440, 3, 13, 32) powinien trwać około 5.35GiB nieskompresowanego, więc jeśli naprawdę miał 8.3GB wolnego, adresowalnych pamięci wtedy w zasadzie powinieneś być w stanie załadować tablicę.

Jednak na podstawie odpowiedzi w komentarzach poniżej używasz 32-bitowych wersji Pythona i numpy. W systemie Windows: a 32 bit process can only address up to 2GB of memory (lub 4 GB, jeśli plik binarny został skompilowany z flagą IMAGE_FILE_LARGE_ADDRESS_AWARE, większość 32-bitowych dystrybucji Pythona nie jest). W związku z tym proces w Pythonie jest ograniczony do 2 GB przestrzeni adresowej, niezależnie od tego, ile masz fizycznej pamięci.

Można zainstalować 64-bitowe wersje Pythona, numpy i dowolnej innej biblioteki Pythona, lub żyć z limitem 2 GB i próbować obejść to. W tym drugim przypadku możesz uciec z przechowywaniem tablic, które przekraczają limit 2 GB, głównie na dysku (np. Przy użyciu np.memmap), ale radzę wybrać opcję # 1, ponieważ operacje na tablicach z zapisem memem są w większości przypadków wolniejsze. niż dla zwykłych np.array s rezydujących całkowicie w pamięci RAM.


Jeśli masz już inną maszynę, która ma wystarczającej ilości pamięci RAM, aby załadować całą tablicę w pamięci rdzeniowej następnie Proponuję zapisać tablicę w innym formacie (jako zwykły np.memmap binarny, a może lepiej, w plik HDF5 z wykorzystaniem PyTables lub H5py). Możliwe jest również (choć nieco trudniejsze), aby wyodrębnić szereg problemów z pliku .npz bez ładowania go do pamięci RAM, dzięki czemu można następnie otworzyć go jako np.memmap tablica znajdująca się na dysku:

import numpy as np 

# some random sparse (compressible) data 
x = np.random.RandomState(0).binomial(1, 0.25, (1000, 1000)) 

# save it as a compressed .npz file 
np.savez_compressed('x_compressed.npz', x=x) 

# now load it as a numpy.lib.npyio.NpzFile object 
obj = np.load('x_compressed.npz') 

# contains a list of the stored arrays in the format '<name>.npy' 
namelist = obj.zip.namelist() 

# extract 'x.npy' into the current directory 
obj.zip.extract(namelist[0]) 

# now we can open the array as a memmap 
x_memmap = np.load(namelist[0], mmap_mode='r+') 

# check that x and x_memmap are identical 
assert np.all(x == x_memmap[:]) 
+0

Podejrzewam, że tablica może wymagać ciągłego zakresu wirtualnej przestrzeni pamięci, przynajmniej dla niektórych jej części. –

+1

Mogę też być, że używa procesu x32, który jest ograniczony do przestrzeni adresowej 4GB. –

+0

@ atomh33ls można potwierdzić, czy korzystasz z 32-bitowego systemu Windows, czy w inny sposób ograniczasz się do 4 GB przestrzeni adresowej? Czy jesteś w stanie przydzielić nową macierz numb 4GB (np. 'Foo = np.ones (536870912, np.float64)')? –