Добавление большого объема данных в базу данных таблиц (HDF5), где database.numcols! = Newdata.numcols? - PullRequest
2 голосов
/ 07 сентября 2011

Я пытаюсь добавить большой набор данных (> 30 ГБ) в существующую таблицу pytables. Таблица состоит из N столбцов, а набор данных - из N-1 столбцов; один столбец рассчитывается после того, как я знаю другие столбцы N-1.

Я использую numpy.fromfile() для чтения фрагментов набора данных в память перед добавлением его в базу данных. В идеале я хотел бы вставить данные в базу данных, затем рассчитать последний столбец и завершить, используя Table.modifyColumn() для завершения операции.

Я рассмотрел добавление numpy.zeros((len(new_data), N)) к таблице, а затем использование Table.modifyColumns() для заполнения новых данных, но я надеюсь, что кто-то знает хороший способ избежать создания огромного массива пустых данных для каждого чанка, который Мне нужно добавить.

Ответы [ 2 ]

1 голос
/ 07 сентября 2011

Если столбцы имеют одинаковый тип, вы можете использовать numpy.lib.stride_tricks.as_strided, чтобы сделать массив, который вы читаете из файла формы (L, N-1), похожим на форму (L, N).Например,

In [5]: a = numpy.arange(12).reshape(4,3)

In [6]: a
Out[6]: 
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11]])

In [7]: a.strides
Out[7]: (24, 8)

In [8]: b = numpy.lib.stride_tricks.as_strided(a, shape=(4, 4), strides=(24, 8))

In [9]: b
Out[9]: 
array([[  0,   1,   2,   3],
       [  3,   4,   5,   6],
       [  6,   7,   8,   9],
       [  9,  10,  11, 112]])

Теперь вы можете использовать этот массив b для заполнения таблицы.Последний столбец каждой строки будет таким же, как первый столбец следующей строки, но вы перезапишете их, когда сможете вычислить значения.

Это не будет работать, если a - массив записей(т.е. имеет сложный тип d).Для этого вы можете попробовать numpy.lib.recfunctions.append_fields.Поскольку он скопирует данные в новый массив, он не сэкономит вам значительный объем памяти, но позволит вам выполнять всю запись одновременно.

1 голос
/ 07 сентября 2011

Вы можете добавить результаты в другую таблицу.Если нет какой-либо веской причины для того, чтобы вычисляемый столбец был смежным с другими столбцами, это, вероятно, самый простой способ.В любом случае есть что сказать, чтобы отделить необработанные данные от расчетов.

Если вам нужно увеличить размер таблицы, используйте h5py .Это обеспечивает более прямой интерфейс к файлу h5.Имейте в виду, что в зависимости от того, как набор данных был создан в файле h5, может оказаться невозможным просто добавить столбец к данным.См. Раздел 1.2.4, «Пространство данных» в http://www.hdfgroup.org/HDF5/doc/UG/03_DataModel.html для обсуждения общего формата данных.h5py поддерживает resize , если базовый набор данных поддерживает его.

Вы также можете использовать один буфер для хранения входных данных, например:

z = zeros((nrows, N))
while more_data_in_file:
    # Read a data block
    z[:,:N-1] = fromfile('your_params')
    # Set the final column
    z[:,N-1:N] = f(z[:,:N-1])
    # Append the data
    tables_handle.append(z)
...