hdf5: фрагментация увеличивает размер данных до 100%

В настоящее время я пишу скрипт на Python, чтобы объединить множество маленьких и не фрагментированных файлов.h5 (~7 МБ каждый). Общее дисковое пространство для всех файлов составляет несколько ГБ.

Каждый файл имеет два набора данных (тип uint8 и float32) с формой (строки, 11, 13, 18) и (строки, 6). Количество строк для каждого файла немного отличается (~ тысячи). Чтобы объединить файлы, мне нужно создать набор выходных данных по частям (maxshape).

Теперь я заметил, что полученный выходной файл занимает гораздо больше дискового пространства, чем для отдельных файлов, например, 7 МБ +7 МБ = 22 МБ.

Чтобы упростить проблему, можно также использовать n = 1 файлы для объединения, то есть преобразовать файл из не разделенного на части в файл.h5.
Если я вручную установлю небольшой размер фрагмента =2, результат будет 7 МБ (без чанковки) -> 7 МБ (с чанкованием).
Однако, если я увеличу размер фрагмента более чем на тысячу, требуемое дисковое пространство почти удвоится: 7 МБ (без чанковки) -> 14 МБ (с чанкованием).

Теперь я действительно задаюсь вопросом, почему такая большая разница между чанкированным и не чанкованным файлом.h5?

Вот выходные данные h5stat файлов chunksize=2 и chunksize=2500:
https://pastebin.com/Gg3LGQkk (2), https://pastebin.com/jUbfemp0 (2500).
Похоже, не метаданные, а сырые данные являются проблемой.

Является ли увеличенный размер диска нормальным для фрагментированного файла.h5? И если да, имеет ли смысл хранить мои данные с кусками? Позже я читаю большой конкатенированный файл.h5 строка за строкой, поэтому мне интересно, будет ли не разделенный на части файл.h5 (меньше по размеру диска) работать с вводом-выводом намного медленнее.

Фрагмент кода с реализацией h5py:

import h5py
#remove file_2 for the simplest non-chunked -> chunked conversion
file_list = [file_1.h5, file_2.h5] # not chunked, e.g. 2866 and 2825 rows
file_output = h5py.File('test.h5', 'w')

cum_rows_list = [0, 2866, 5691] # cumulative number of rows for the input

for n, input_file_name in enumerate(file_list):

    print 'Processing file ' + file_list[n]
    input_file = h5py.File(input_file_name, 'r')

    for folder_name in input_file:

        folder_data = input_file[folder_name] 
        if n == 0:
            # first file; create the dummy dataset with no max shape
            maxshape = (None,) + folder_data.shape[1:]

            # create chunked output dataset
            output_dataset = file_output.create_dataset(
            folder_name, data=folder_data, maxshape=maxshape, 
            chunks=(2500,) + folder_data.shape[1:])
            output_dataset.resize(cum_rows_list[-1], axis=0)

        else:
            # not important for only one file
            ...

    file_output.flush()

file_output.close()

Обновление: как указал Яр в комментариях, разница в размере файла основана на заполнении из-за указанного размера фрагмента.

0 ответов

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