Итеративная запись в магазины HDF5 в Pandas

В Pandas есть следующие примеры того, как хранить Series, DataFrames и Panelsв файлах HDF5. :

Подготовьте некоторые данные:

In [1142]: store = HDFStore('store.h5')

In [1143]: index = date_range('1/1/2000', periods=8)

In [1144]: s = Series(randn(5), index=['a', 'b', 'c', 'd', 'e'])

In [1145]: df = DataFrame(randn(8, 3), index=index,
   ......:                columns=['A', 'B', 'C'])
   ......:

In [1146]: wp = Panel(randn(2, 5, 4), items=['Item1', 'Item2'],
   ......:            major_axis=date_range('1/1/2000', periods=5),
   ......:            minor_axis=['A', 'B', 'C', 'D'])
   ......:

Сохраните в магазине:

In [1147]: store['s'] = s

In [1148]: store['df'] = df

In [1149]: store['wp'] = wp

Осмотрите, что есть в магазине:

In [1150]: store
Out[1150]: 
<class 'pandas.io.pytables.HDFStore'>
File path: store.h5
/df            frame        (shape->[8,3])  
/s             series       (shape->[5])    
/wp            wide         (shape->[2,5,4])

Закрыть магазин:

In [1151]: store.close()

Вопросы:

  1. В приведенном выше коде когда данные фактически записываются на диск?

  2. Скажем, я хочу добавить тысячи больших фреймов данных, живущих в файлах .csv, в один файл .h5. Мне нужно будет загрузить их и добавить в файл .h5 одну за другой, так как я не могу позволить себе хранить их все в памяти сразу, так как они занимают слишком много памяти. Возможно ли это с HDF5? Как правильно это сделать?

  3. #P4# <блочная цитата> #P5# #P6#

person Amelio Vazquez-Reina    schedule 19.05.2013    source источник


Ответы (2)


  1. Как только оператор будет выполнен, например, store['df'] = df. close просто закрывает фактический файл (который будет закрыт для вас, если процесс существует, но выведет предупреждающее сообщение)

  2. Прочтите раздел http://pandas.pydata.org/pandas-docs/dev/io.html#storing-in-table-format

    Как правило, не рекомендуется размещать МНОГО узлов в файле .h5. Возможно, вы захотите добавить и создать меньшее количество узлов.

    Вы можете просто перебрать их .csv и store/append один за другим. Что-то типа:

    for f in files:
      df = pd.read_csv(f)
      df.to_hdf('file.h5',f,df)
    

    Было бы в одну сторону (создание отдельного узла для каждого файла)

  3. Не добавляется - как только вы его напишете, вы можете получить его только сразу, например. нельзя выбрать подраздел

    Если у вас есть таблица, вы можете делать такие вещи, как:

    pd.read_hdf('my_store.h5','a_table_node',['index>100'])
    

    что похоже на запрос к базе данных, только получение части данных

    Таким образом, хранилище нельзя добавить или запросить, а таблицу можно сделать и тем, и другим.

person Jeff    schedule 19.05.2013
comment
Спасибо, я немного смущен вашим ответом на 2). Почему вы передаете f df.to_hdf? Кроме того, есть ли разница между df.to_hdf и store['df'] = df? Наконец, я запутался в том, как узлы связаны с кодом выше. Обязательно ли store['df'] = df создает новый узел в файле? Есть ли способ добавить несколько DataFrames в один hdf5 в пределах одного узла? - person Amelio Vazquez-Reina; 19.05.2013
comment
имя узла f, store[f] = pd.read_csv(f) эквивалентно df.to_hdf`, but the df.to_hdf`` автоматически открывает/закрывает магазин для вас. store['df'] = df создает/перезаписывает узел с именем 'df'. К вашему сведению, продолжать это делать не рекомендуется, см. раздел об удалении данных. Узел может содержать только один объект (например, фрейм), но вы можете создать иерархию узлов, если хотите (например, node_a/df, node_a/sub_node/df эффективно содержит несколько фреймов в одном узле). - person Jeff; 19.05.2013
comment
Большое спасибо, Джефф. Кстати, какие импорты/пакеты мне нужны для использования HDFStore(), добавления таблиц и использования read/write_hdf в Pandas? - person Amelio Vazquez-Reina; 19.05.2013
comment
pandas.pydata.org/pandas-docs/dev/, numexpr и PyTables - person Jeff; 19.05.2013
comment
Фантастический. Спасибо, Джефф. Не могли бы вы немного рассказать о том, почему иметь слишком много узлов в .h5 — плохая идея? (например, 500K будет слишком много?). Помимо добавления dfs в таблицы, есть ли другой способ сгруппировать 100 КБ кадров данных в одном файле .h5, не создавая слишком много узлов? - person Amelio Vazquez-Reina; 19.05.2013
comment
время доступа может ухудшиться с таким количеством узлов; Вам гораздо лучше иметь гораздо большие таблицы с меньшим количеством строк. насколько велик примерно каждый csv (строки/столбцы)? они связаны? какой у вас шаблон доступа для получения данных? - person Jeff; 19.05.2013
comment
вот ссылка 2 некоторых рецепта: pandas.pydata.org/pandas-docs /dev/cookbook.html#hdfstore - person Jeff; 20.05.2013
comment
Очень полезно Джефф. Спасибо! Кстати, я сталкиваюсь с некоторыми странными проблемами, следуя этому маршруту при сохранении одного DataFrame: stackoverflow.com/questions/16639503/ - person Amelio Vazquez-Reina; 20.05.2013

Отвечая на вопрос 2, с pandas 0.18.0 вы можете сделать:

store = pd.HDFStore('compiled_measurements.h5')
for filepath in file_iterator:
    raw = pd.read_csv(filepath)
    store.append('measurements', raw, index=False)

store.create_table_index('measurements', columns=['a', 'b', 'c'], optlevel=9, kind='full')
store.close()

На основе этой части документации.

В зависимости от того, сколько у вас данных, создание индекса может потреблять огромное количество памяти. Документация PyTables описывает значения optlevel.

person Pablo    schedule 16.08.2016