'/' в именах в файловой системе 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.