2011-09-30 10 views
14

Mam dość duży plik HDF5 wygenerowany przez PyTables, który próbuję odczytać w klastrze. Występuje problem z NumPy podczas czytania w pojedynczej porcji. Chodźmy na przykładzie:Wyjątek Floating Point z Numpy i PyTables

Całkowity kształt tablicy ciągu w pliku HDF5 jest

In [13]: data.shape 
Out[13]: (21933063, 800, 3) 

Każdy wpis w tej tablicy jest np.float64.

Mam każdy węzeł czytać plasterki o rozmiarze (21933063,10,3). Niestety, NumPy wydaje się nie być w stanie odczytać wszystkich 21 milionów podsystemów jednocześnie. Próbowałem zrobić to kolejno dzieląc się te plastry na 10 plastrów o wymiarach (2193306,10,3) a następnie przy użyciu następujących zmniejszyć dostać rzeczy działa:

In [8]: a = reduce(lambda x,y : np.append(x,y,axis=0), [np.array(data[i*  \ 
     chunksize: (i+1)*chunksize,:10],dtype=np.float64) for i in xrange(k)]) 
In [9]: 

gdzie 1 <= k <= 10 i chunksize = 2193306. Ten kod działa dla k <= 9; w przeciwnym razie pojawia się następujący:

In [8]: a = reduce(lambda x,y : np.append(x,y,axis=0), [np.array(data[i*  \ 
     chunksize: (i+1)*chunksize,:10],dtype=np.float64) for i in xrange(k)]) 
Floating point exception 
[email protected] 00:00:00 ~ 
$ 

Próbowałem za pomocą memcheck narzędzie Valgrind jest dowiedzieć się, co się dzieje i wydaje się jakby PyTables jest winowajcą. Dwa główne pliki, które pojawiają się w śledzeniu, to libhdf5.so.6 i plik powiązany z blosc.

Należy również pamiętać, że jeśli mam k=8, otrzymuję:

In [12]: a.shape 
Out[12]: (17546448, 10, 3) 

Ale jeśli dołączyć ostatnią subslice, otrzymuję:

In [14]: a = np.append(a,np.array(data[8*chunksize:9*chunksize,:10], \ 
     dtype=np.float64)) 
In [15]: a.shape 
Out[15]: (592192620,) 

Czy ktoś ma jakieś pomysły, co zrobić ? Dzięki!

+0

Jaki jest błąd, który pojawia się po odczytaniu danych bezpośrednio do tablicy numpy? Sugerowałbym, abyś wcześniej przydzielił tablicę docelową, zamiast próbować ją zbudować, dołączając wiele tablic. – DaveP

Odpowiedz

1

Czy próbowałeś przydzielić tak dużą tablicę wcześniej (jak sugeruje DaveP)?

In [16]: N.empty((21000000,800,3)) 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
... 
ValueError: array is too big. 

To jest na 32-bitowym Pythonie. Potrzebowałbyś 20e6 * 800 * 3 * 8/1e9 = 384 GB pamięci! Jeden Float64 potrzebuje 8 bajtów. Czy naprawdę potrzebujesz całej tablicy naraz?

Przepraszamy, nie czytałem poprawnie.

Twoja tablica z osiami k = 8 ma już około 4,1 GB. Może to jest problem?

Czy to działa, jeśli używasz tylko zamiast do ostatniego wymiaru?

Kolejna propozycja, chciałbym najpierw spróbować, aby zmienić rozmiar tablicy, a następnie wypełnić go:

a = zeros((4,8,3)) 
a = resize(a, (8,8,3)) 
a[4:] = ones((4,8,3))