Доступ к наборам данных в файлах HDF5, содержащих необычные типы данных - PullRequest
0 голосов
/ 11 октября 2019

Я хочу проанализировать некоторые наборы данных в файле .h5, который мне дали, используя что-то вроде Pandas, однако я столкнулся с проблемой, которая, как представляется, является результатом того, что некоторые типы данных в наборах данных не поддерживаются инструментами, которые я использовалдо сих пор. Я немного перечитал, но я недостаточно хорошо разбираюсь в инструментах и ​​проблемах, чтобы эффективно устранять неполадки, и ищу рекомендации по этому вопросу.

Я могу получить доступ к наборам данных, используя HDFView, но с помощью этогоэкспортировать все данные в текстовые файлы, а затем считывать эти текстовые файлы во что-то еще, что не идеально, и, кроме того, не всегда распечатывать данные в формате, который я знаю, как использовать (то есть, логические значения выводятся как что-то вроде B@38b27cdc скаждое такое выражение кажется уникальным). Я попытался несколько попыток доступа к файлу с помощью Python (h5py и PyTables) и MATLAB. Некоторые примеры кода и выходные данные приведены ниже.

h5py пример с использованием numpy

f = h5py.File('filename.h5', 'r')
group = f["Run 1"]
dataset = group["datasetIAmInterestedIn"]

Вывод ошибки и окончание. Дайте мне знать, если вы хотите увидеть полный вывод здесь.

TypeError: No NumPy equivalent for TypeBitfieldID exists

Пример PyTable

f = tab.File('filename.h5', 'r')
group = f.get_node("/Run 1")
group.datasetIAmInterestedIn

Вывод команды

/Run 1/datasetIAmInterestedIn(UnImplemented(58023,)) ''
NOTE: The UnImplemented object represents a PyTables unimplemented dataset present in the 'filename.h5' HDF5 file.  If you want to see this kind of HDF5 dataset implemented in PyTables, please contact the developers.

(я включилэто в случае, если это полезно)

MATLAB

data = hdf5read("filename.h5","/Run 1/datasetIAmInterestedIn")

Вывод команды

Error using hdf5readc
Call to HDF5 library failed (unsupportedDatatype): "Datatype of an attribute value is not supported. Please disable the
reading of attribute values by setting the 'ReadAttributes' argument
to false. Type HELP HDF5INFO for more information.".

Error in hdf5read (line 100)
[data, attributes] = hdf5readc(settings.filename, ...

Мои попытки изучения использования ReadAttributes не дали никакой полезной информацииили результаты.

1 Ответ

1 голос
/ 11 октября 2019

Если у вас составной тип данных, вам нужно определить состав, прежде чем вы сможете его прочитать. Например (а здесь код находится в MATLAB) у вас есть составной тип данных, в котором хранятся записи журнала со строками (разных размеров), число с плавающей запятой двойной точности, в котором хранятся дата и время, и целочисленный идентификатор:

char32_type = H5T.copy('H5T_FORTRAN_S1');
H5T.set_size(char32_type, 32);
char32_size = H5T.get_size(char32_type);

char64_type = H5T.copy('H5T_FORTRAN_S1');
H5T.set_size(char64_type, 64);
char64_size = H5T.get_size(char64_type);

int_type = H5T.copy('H5T_NATIVE_INT');
int_size = H5T.get_size(int_type);

dbl_type = H5T.copy('H5T_NATIVE_DOUBLE');
dbl_size = H5T.get_size(dbl_type);

sizes = [
    char32_size
    dbl_size
    char64_size
    int_size
    ];

offset = [ 0 ; cumsum(sizes) ]; % zero-based

log_type = H5T.create('H5T_COMPOUND', sum(sizes));
H5T.insert(log_type, 'user',        offset(1), char32_type);
H5T.insert(log_type, 'datetime',    offset(2), dbl_type);
H5T.insert(log_type, 'action',      offset(3), char64_type);
H5T.insert(log_type, 'id',          offset(4), int_type);

Вы можете использовать этот составной тип log_type для чтения / записи данных. Например, для чтения набора данных /log в файле HDF5 что-то вроде следующего:

plist     = 'H5P_DEFAULT';
fid       = H5F.open(log_file ,'H5F_ACC_RDONLY', plist);
log_dset  = H5D.open(fid, '/log');
mem_space = 'H5S_ALL';
log = H5D.read(log_dset, log_type, mem_space, 'H5S_ALL', 'H5P_DEFAULT');


% Close the dataset and file once you're done
H5D.close(log_dset);
H5F.close(fid);

Выводом чтения (log) будет структура. Строки будут символьными массивами в неудобном формате столбцов, поэтому их необходимо будет транспонировать. Здесь я конвертирую их в массивы ячеек, но вы можете захотеть использовать класс String или иначе. Я конвертирую дату и время в массив дат в строковом формате. Поле id в порядке и не требует обработки.

log.user    = cellstr(log.user');
log.action  = cellstr(log.action');
log.datestr = cellstr(datestr(log.datetime));
% log.id is okay as is

Если вы не знаете формат составного типа, у вас могут возникнуть проблемы?

...