'/' в именах в файловой системе HDF5
Я испытываю некоторые действительно странные взаимодействия между h5py, PyTables (через Pandas) и С++ сгенерированный HDF5. Кажется, что h5check и h5py, похоже, справляются с именами типов, содержащими '/', но Pandas/PyTables не может. Ясно, что в моем понимании есть пробел, поэтому:
Что я здесь не понял?
Детали gory
У меня есть следующие данные в файле HDF5:
[...]
DATASET "log" {
DATATYPE H5T_COMPOUND {
H5T_COMPOUND {
H5T_STD_U32LE "sec";
H5T_STD_U32LE "usec";
} "time";
H5T_IEEE_F32LE "CIF/align/aft_port_end/extend_pressure";
[...]
Это было создано через С++ API. Утилита h5check говорит, что файл действителен.
Обратите внимание, что CIF/align/aft_port_end/extend_pressure
не означает путь к группе /node/leaf. Это метка, которую мы используем внутри, которая имеет внутреннюю структуру, которая содержит "/" в качестве разделителей. Мы не хотим, чтобы файл HDF5 знал об этом: ему все равно. Ясно, что если '/' являются незаконными в любом имени HDF5, тогда мы должны изменить этот разделитель на что-то еще.
Использование PyTables (хорошо, Pandas, но использует PyTables внутренне), чтобы прочитать файл, я получаю
>>> import pandas as pd
>>> store = pd.HDFStore('data/XXX-20150423-071618.h5')
>>> store
/home/XXX/virt/env/develop/lib/python2.7/site-packages/tables/group. py:1156: UserWarning: problems loading leaf ``/log``::
the ``/`` character is not allowed in object names: 'XXX/align/aft_port_end/extend_pressure'
The leaf will become an ``UnImplemented`` node.
Я спросил об этом в этом вопросе и сказал, что '/' незаконно в спецификации. Тем не менее, все становится страннее с h5py...
Используя h5py, чтобы прочитать файл, я получаю то, что хочу:
>>> f['/log'].dtype
>>> dtype([('time', [('sec', '<u4'), ('usec', '<u4')]), ('CI
F/align/aft_port_end/extend_pressure', '<f4')[...]
Это более или менее то, что я изложил.
Нет нужды говорить, я смущен. Мне удалось создать незаконный h5check? Является PyTables, не поддерживающим этот случай края?... Я смущен.
Ясно, что я мог бы написать простую оболочку примерно так:
>>> import matplotlib.pyplot as plt
>>> silly = pd.DataFrame(f['/log']['CIF/align/aft_port_end/extend_pressure'])
>>> silly.plot()
>>> plt.show()
чтобы получить все данные из файла HDF5 в Pandas. Однако я не уверен, что это хорошая идея из-за путаницы раньше. Мое самое большое беспокойство заключается в том, что преобразование может не масштабироваться, если данные очень большие...
Ответы
Ответ 1
Я немного просмотрел h5check source, и я не могу найти места, где он проверяет, содержит ли имя косую черту. Вы можете просмотреть сообщения об ошибках, которые оно может произвести с помощью:
grep error_push h5checker.c -A1
В приведенных вами ссылках четко указано, что в именах объектов не разрешены косые черты. Так что да, я думаю, что вы сделали файл, который является незаконным, но передает h5check. Инструмент, похоже, больше фокусируется на компоновке двоичных данных. Ближайшая связанная проверка, которую я могу найти, - это защита от повторяющихся имен.
По-моему, все есть. Тот факт, что h5py
и другие библиотеки каким-то образом могут создавать или читать этот незаконный файл, не имеет значения. Спектр говорит: "Не помещайте слэши в имена объектов", так что вы этого не делаете. Конец истории.
Если вы не уверены, подумайте об этом так: если вам удалось создать обычный файл с косой чертой в имени файла, что произойдет? Большинство программ предполагают, что имена файлов не содержат косой черты и, следовательно, они могут разбить путь к каталогу, разделив его на символы косой черты. Ваш файл нарушит это поведение и таким образом представит много тонких (и не очень тонких) ошибок. Пользователи будут жаловаться, программисты будут вас ненавидеть, системные администраторы проклинают вас.
Также можно с уверенностью предположить, что рядом с PyTables
многие другие библиотеки и программы не смогут обрабатывать косые черты в именах переменных. Хорошая вещь о HDF заключается в том, что для этого существует множество инструментов, и, используя косые черты, вы выбрасываете это преимущество. Вы можете подумать, что это не важно, возможно, ваши файлы HDF-5 предназначены только для внутреннего использования. Однако ситуация может измениться через 5 лет, как это обычно бывает.
Просто укусите пулю и замените '/' на '|' перед записью переменных в HDF5. Заменяйте их назад, когда вы их читаете. Время, которое вы теряете, реализуя это, вы вернете x-fold (для x > 1), избегая будущих ошибок и жалоб пользователей.
Извините за написание, но я надеюсь убедить вас.
Ответ 2
Не могли бы вы использовать h5py
, чтобы читать все ваши файлы и переписывать их без оскорбительных символов, чтобы pytables
может их прочитать?
Если это вне спецификации, я предполагаю, что вы испытываете только то, что некоторые реализации обрабатывают его, а другие не...
Ответ 3
Убедитесь, что вы создаете группы, а не только имя пути, справа - это, вероятно, ошибка, в которой возникает ошибка. Если вы создаете группы для своих объектов, а затем называете объекты именами листов (extend_pressure выше), вы проблем не будет.
H5py - довольно тонкая обертка вокруг библиотеки C HDF5, pandas/pytables намного более тяжелые в подходе - или, по крайней мере, они имеют больше своей собственной семантики, и поэтому они проверяют, чтобы сделать убедитесь, что у вас нет имени//в ваших именах объектов. Но имейте в виду, что каждый использует библиотеку HDF5 в конце дня, потому что в то время как HDF5 велик, было бы огромной попыткой сделать альтернативную реализацию - за пределами ресурсов pandas/Pytables.
Незначительная оговорка: раньше я взломал внутренние элементы HDF5 и H5py.