【问题标题】:Accessing datasets in HDF5 files containing unusual datatypes访问包含异常数据类型的 HDF5 文件中的数据集
【发布时间】:2020-02-08 16:56:16
【问题描述】:

我想分析一个 .h5 文件中的一些数据集,我使用 Pandas 之类的工具提供,但是我遇到了一个问题,似乎是由于我使用的工具不支持数据集中的某些数据类型迄今为止。我已经阅读了一些内容,但我对工具和问题的理解还不够好,无法有效地进行故障排除,我正在寻求有关此问题的指导。

我可以使用HDFView 访问数据集,但是使用它将所有数据导出到文本文件,然后将这些文本文件读入其他文件并不理想,而且并不总是以我的格式打印出数据知道如何使用(即布尔值打印为B@38b27cdc 之类的东西,每个这样的表达式看起来都是唯一的)。 我尝试了一些使用 python(h5py 和 PyTables)和 MATLAB 访问文件的尝试。下面给出了一些代码示例和输出。

使用 numpy 的 h5py 示例

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 的用法并没有产生任何有用的信息或结果。

【问题讨论】:

  • Python h5py 不支持布尔值/位域(参见github.com/HDFGroup/h5serv/issues/1github.com/h5py/h5py/issues/109)。 MATLAB 确实在 HDF5 中支持它们,但你的错误提到了属性,而不是数据集,这看起来很奇怪,因为你描述了这个问题。我想知道的唯一另一件事是数据集名称中的空格是否导致问题?但是,如果没有 HDF5 文件和实际代码,将很难调试。
  • 我承认我的无知在这里可能有点误导。我已经确定组中每个数据集的数据类型由元数据组定义(?看起来是这样)并且数据类型是“复合”。这会改变事情吗?我有点不愿意分享数据集,因为虽然它不包含任何敏感信息,但我为之做这件事的公司可能会采取暗淡的态度,我不想冒险。
  • 如果它是复合的,那么您需要先构建复合数据类型才能读取它(至少在 MATLAB 中,我假设它在 Python 中是相同的,但我没有尝试过)。我看看能不能贴一些代码...
  • 顺便说一下,为了分享知识:从 2.10 版开始,h5py 可以处理位域。刚刚看到这个docs.h5py.org/en/latest/whatsnew/2.10.html 并认为我应该分享它
  • 很高兴了解位域,看来我落后了几年!

标签: python matlab hdf5 h5py pytables


【解决方案1】:

如果您有复合数据类型,则需要先定义复合数据类型,然后才能读取它。 例如(这里的代码在 MATLAB 中)你有一个复合数据类型,它存储带有字符串(不同大小)的日志条目,一个存储日期时间和整数 ID 的双精度浮点数:

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 来读取/写入数据。例如。用于读取 HDF5 文件中的数据集/log,然后类似于以下内容:

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) 的输出将是一个结构。字符串将是不方便的列格式的 char 数组,因此需要转置。在这里,我将它们转换为元胞数组,但您可能需要 String 类或其他类。我将日期时间转换为字符串格式的日期数组。 id 字段很好,不需要修整。

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

如果你不知道复合类型的格式,那你就麻烦了?

【讨论】:

  • 我想我明白了。让我在这里检查一下我的理解。在其中一个数据集中,我在 Compound 中有以下数据集成员:3 个 64 位浮点数、2 个 8 位位域、2 个 64 位浮点数组、2 个 32 位整数和一个可变长度字符串。如果我以您对每个单独的浮点数、整数、数组等的方式创建一个唯一 id,并将它们分配给一个对象,以便在您拥有的读取函数期间调用,MATLAB 应该能够读取该特定数据集吗?
  • 您不需要唯一的 ID(我只是碰巧想在我的用例中存储一个我称为 id 的 int)。您需要定义一次复合类型(即从 10 个浮点数、整数等中构建您自己的 log_type 版本),然后使用您的 log_type 版本来读取数据。 log_type 只是告诉 HDF5 复合数据的格式,因此您只需要其中一个,并且可以重复使用它来读取/写入。
  • 好的,非常感谢。最后一个问题:我插入 log_type 的 id 是否需要与复合数据集成员的 id 匹配?即数组 id 之一是 Data Value->Data Value->Ray->Direction [X;Y;Z](m) 。我需要在构造的复合类型中匹配每个这样的 id 吗?
  • 我不明白你的问题! id 没有什么特别之处,只是一个字段名。我可以将其重命名为foolog_type 仅定义复合类型中字段的类型(int、float 等)和顺序。它对 ID 或索引或任何东西一无所知,它只是说“文件中的字节按此顺序与这些字段相关”。log_type 不存储任何数据,它只是定义数据布局。
  • 对不起,我的意思是.h5文件中的复合数据集成员都已经命名了。我想知道是否必须匹配我创建的log-type 中的这些名称。
猜你喜欢
  • 2019-02-04
  • 2014-03-23
  • 2014-09-12
  • 2019-08-02
  • 2022-08-10
  • 2022-10-12
  • 2016-06-02
  • 2019-04-04
  • 2020-05-28
相关资源
最近更新 更多