чтение кусков hdf файла с использованием панд read_hdf занимает слишком много времени - PullRequest
0 голосов
/ 29 января 2019

У нас проблема в том, что нам нужно сохранить временный кадр данных из ~ 10 столбцов смешанных данных (float / int) на диске, а затем прочитать и обработать его впоследствии.

Кадр данных реальной ситуации будет ~> 300 миллионов строк, что приводит к сжатому hdf-файлу размером 10 ГБ +, поэтому мы не можем позволить себе читать все это в памяти и обрабатывать его по частям.

По нашему опыту - запись в hdf с использованием панд выполняется быстро:

chunks = map(job, range(num_chunks))
append = False
for chunk in chunks:
chunk.to_hdf(output,
             key='results',
             format='table',
             complevel=9,
             complib="blosc:snappy",
             append=append)
append = True

, где job - это функция, которая возвращает фрагмент данных.В реальной ситуации мы генерируем порции, используя multiprocessing, но это не имеет никакого отношения к проблеме ...

Однако чтение занимает слишком много времени - кажется, даже неадекватным - я уверен, что я делаю что-то не тактам:

res = pd.read_hdf(output,key='results',iterator=True,chunksize=chunksize_read)
## Do some silly computation on each chunk here
## real-life processing is going to be some histogramming
compute_res = [ _['a'].mean() for _ in res ]

Некоторые моменты реального времени - ~ 2 минуты для генерации ~ 10 ГБ hdf и ~ 40 + минут (!!!) для чтения полученного файла ...

Проблемакажется, не связаны со смешанными типами данных в кадре данных ... Я создал супер-минимальный пример , где я могу воспроизвести ту же проблему с кадром данных всего в 1 столбце с плавающей запятой (!).

Вот некоторые примеры использования этого минимального примера:

time took to write 50000000 elements  in 100 chunks to xxx.h5: 15.09 sec
time took to read 50000000 elements  in chunks of 100 and to do a mock  computation per chunk: 322.29 sec
time took to read 50000000 elements in RAM at once and to do a mock  computation: 0.87 sec

Любая помощь приветствуется!Спасибо!

PS

Нам даже не нужно использовать hdf для этого ... Но мы бы очень хотели сохранить его в pandas API - то есть dataframe_chunk.to_whatever(fname,some_nice_compression=True)с одной стороны и for chunk in pandas.from_whatever(fname,iterator=True ...): do_stuff(chunk) с другой стороны.

...