pandas pytables append: производительность и увеличение размера файла

У меня больше 500 PyTables магазины, которые содержат около 300 МБ данных каждый. Я хотел бы объединить эти файлы в большой магазин, используя панд append как в коде ниже.

def merge_hdfs(file_list, merged_store):
    for file in file_list:
        store = HDFStore(file, mode='r')
        merged_store.append('data', store.data)
        store.close()

Операция добавления выполняется очень медленно (для добавления одного хранилища в течение 10 минут требуется merged_store) и, как ни странно, размер файла merged_store кажется, увеличивается на 1 Гб для каждого добавленного магазина.

Я указал общее число ожидаемых строк, которое, согласно документации, должно улучшить производительность, и прочитав " Улучшить производительность записи таблицы HDF5 для панд (PyTables?)", Я ожидал большого времени записи, но почти 10 минут на каждые 300 МБ кажутся слишком медленными., и я не могу понять, почему увеличение в размере.

Интересно, я что-то упустил?

Для получения дополнительной информации, вот описание одного из 500 PyTables.

/data/table (Table(272734,)) ''
  description := {
  "index": Int64Col(shape=(), dflt=0, pos=0),
  "values_block_0": Float64Col(shape=(6,), dflt=0.0, pos=1),
  "id": StringCol(itemsize=11, shape=(), dflt='', pos=2),
  "datetaken": Int64Col(shape=(), dflt=0, pos=3),
  "owner": StringCol(itemsize=15, shape=(), dflt='', pos=4),
  "machine_tags": StringCol(itemsize=100, shape=(), dflt='', pos=5),
  "title": StringCol(itemsize=200, shape=(), dflt='', pos=6),
  "country": StringCol(itemsize=3, shape=(), dflt='', pos=7),
  "place_id": StringCol(itemsize=18, shape=(), dflt='', pos=8),
  "url_s": StringCol(itemsize=80, shape=(), dflt='', pos=9),
  "url_o": StringCol(itemsize=80, shape=(), dflt='', pos=10),
  "ownername": StringCol(itemsize=50, shape=(), dflt='', pos=11),
  "tags": StringCol(itemsize=505, shape=(), dflt='', pos=12)}
  byteorder := 'little'
  chunkshape := (232,)

1 ответ

Решение

Это в основном ответ здесь, на который я недавно ответил.

Суть в том, что вам нужно отключить индексирование store.append('df',df,index=False), При создании магазина индексируйте его в конце.

Кроме того, отключите сжатие при объединении таблиц.

Индексирование - довольно дорогая операция, и, если я правильно помню, используется только один процессор.

Наконец, убедитесь, что вы создали объединенный с mode='w' поскольку все последующие операции добавляются, и вы хотите начать с чистого нового файла.

Я также не буду указывать chunksize авансом. Скорее после того, как вы создали окончательный индекс, выполните сжатие, используя ptrepack и указать chunksize=auto который вычислит это для вас. Я не думаю, что это повлияет на производительность записи, но оптимизирует производительность запросов.

Вы можете попробовать настроить chunksize параметр для append (это размер куска), а также к большему числу.

Очевидно, убедитесь, что каждая из добавляемых таблиц имеет точно такую ​​же структуру (будет повышаться, если это не так).

Я создал эту проблему для улучшения, чтобы сделать это "внутренне": https://github.com/pydata/pandas/issues/6837

Другие вопросы по тегам