Удаление данных из файла HDF5
У меня есть файл HDF5 с одномерным (N x 1) набором составных элементов - на самом деле это временный ряд. Данные сначала собираются в автономном режиме в файл HFD5, а затем анализируются. Во время анализа большая часть данных оказывается неинтересной, и только некоторые ее части интересны. Поскольку набор данных может быть довольно большим, я хотел бы избавиться от неинтересных элементов, сохраняя интересные. Например, сохраните элементы 0-100 и 200-300 и 350-400 набора данных из 500 элементов, оставите остальные. Но как?
Есть ли у кого-нибудь опыт в том, как это сделать с HDF5? По-видимому, это можно сделать несколькими способами, по крайней мере:
- (Очевидное решение), создайте новый свежий файл и напишите необходимые данные по элементам. Затем удалите старый файл.
- Или, в старый файл, создайте новый свежий набор данных, напишите необходимые данные, отсоедините старый набор данных, используя H5Gunlink(), и избавитесь от невостребованного свободного пространства, запустив файл через h5repack.
- Или переместите интересные элементы в существующем наборе данных к началу (например, переместите элементы 200-300 в позиции 101-201 и элементы 350-400 в позиции 202-252). Затем вызовите H5Dset_extent(), чтобы уменьшить размер набора данных. Затем, возможно, запустите h5repack, чтобы освободить свободное пространство.
Поскольку файлы могут быть довольно большими, даже если неинтересные элементы были удалены, я бы предпочел не переписывать их (это займет много времени), но, похоже, требуется освободить свободное пространство. Любые подсказки от экспертов HDF5?
Ответы
Ответ 1
HDF5 (по крайней мере, версия, к которой я привык, 1.6.9) не позволяет удалять. Фактически, это так, но это не освобождает использованное пространство, в результате у вас все еще есть огромный файл. Как вы сказали, вы можете использовать h5ppack, но это пустая трата времени и ресурсов.
Что-то, что вы можете сделать, это иметь боковую базу данных, содержащую логическое значение, сообщая вам, какие значения являются "живыми" и какие из них были удалены. Это не уменьшает размер файла, но, по крайней мере, дает вам быстрый способ выполнить удаление.
Альтернативой является определение сляба на вашем массиве, копирование соответствующих данных, удаление старого массива или доступ к данным через панель, а затем переопределить его по мере необходимости (я никогда не делал этого, хотя, поэтому я не уверен, если это возможно, но это должно)
Наконец, вы можете использовать стратегию монтажа hdf5, чтобы ваши наборы данных находились в "прикрепленном" файле hdf5, который вы монтировали на своем корневом hdf5. Когда вы хотите удалить материал, скопируйте интересные данные в другой смонтированный файл, отключите старый файл и удалите его, а затем перемонтируйте новый файл в нужном месте. Это решение может быть беспорядочным (поскольку у вас есть несколько файлов), но он позволяет вам освобождать место и работать только на подчастих вашего дерева данных, вместо использования repack.
Ответ 2
Копирование данных или использование h5repack, как вы описали, являются двумя обычными способами "сжатия" данных в файле HDF5, к сожалению.
Проблема, как вы могли догадаться, заключается в том, что файл HDF5 имеет сложную внутреннюю структуру (формат файла здесь, для любой, кто любопытен), поэтому удаление и сокращение вещей просто оставляет дыры в файле одинакового размера. Последние версии библиотеки HDF5 могут отслеживать освобожденное пространство и повторно использовать его, но ваш прецедент, похоже, не в состоянии воспользоваться этим.
Как уже упоминалось в другом ответе, вы можете использовать внешние ссылки или функцию виртуального набора данных для создания файлов HDF5, которые были бы более поддающимися тому манипуляциям, которые вы бы делали, но я подозреваю, что вы все равно будете копирование большого количества данных, и это, безусловно, добавит дополнительную сложность и накладные расходы на управление файлами.
H5Gunlink(), кстати, устарел. Предпочтительной заменой является H5Ldelete().