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