Исключение с плавающей точкой с Numpy и PyTables - PullRequest
14 голосов
/ 01 октября 2011

У меня довольно большой файл HDF5, созданный PyTables, который я пытаюсь прочитать в кластере.У меня проблема с NumPy, когда я читаю по отдельности.Давайте рассмотрим пример:

Общая форма массива в файле HDF5 равна

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

Каждая запись в этом массиве имеет вид np.float64.

* 1008.* У меня есть каждый узел читать кусочки размером (21933063,10,3).К сожалению, NumPy, похоже, не может прочитать все 21 миллион субликсов одновременно.Я попытался сделать это последовательно, разделив эти кусочки на 10 кусочков размером (2193306,10,3), а затем используя следующее сокращение, чтобы заставить работать:
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]:

, где 1 <= k <= 10 и chunksize = 2193306.Этот код работает для k <= 9;в противном случае я получаю следующее:

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
home@mybox  00:00:00  ~
$

Я пытался использовать инструмент Valgrind memcheck, чтобы выяснить, что происходит, и кажется, что PyTables является виновником.В трассировке отображаются два основных файла libhdf5.so.6 и файл, связанный с blosc.

Кроме того, обратите внимание, что если у меня есть k=8, я получаю:

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

Но если я добавляю последний сублим, я получаю:

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

у кого есть идеи что делать?Спасибо!

1 Ответ

1 голос
/ 13 октября 2011

Вы пытались выделить такой большой массив раньше (как предлагает DaveP)?

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

Это на 32-битном Python.На самом деле вам потребуется 20e6 * 800 * 3 * 8 / 1e9 = 384 ГБ памяти!Один Float64 требует 8 байтов.Вам действительно нужен весь массив за один раз?

Извините, неправильно прочитал сообщение.

Ваш массив с k = 8 сублицензиями уже имеет размер около 4,1 ГБ.Может быть в этом проблема?

Работает ли это, если вы используете только 8 вместо 10 для последнего измерения?будет пытаться сначала изменить размер массива, а затем заполнить его:

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