【问题标题】:How to access cell variables stored in .mat file using h5py module?如何使用 h5py 模块访问存储在 .mat 文件中的单元格变量?
【发布时间】:2020-04-26 19:22:34
【问题描述】:

我使用 -v7.3 标志保存在 test.mat 文件中的以下数据字段的 MATLAB 变量很少,并希望使用 h5py 模块读回以用于其他目的。

load('test.mat'); % give me this 

struct with fields:
       volume: [4240×1 double]
     centroid: [4240×3 double]
        faces: {4240×1 cell}
          nuc: {4240×1 cell}

我可以读取双字段变量,但无法访问单元字段变量。有什么方法可以从 python 访问 nuc 和 faces 变量吗?

>>>import h5py
>>>name='test.mat' 
>>>f=h5py.File(name)
>>>f.keys()
<KeysViewHDF5 ['#refs#', 'volume', 'centroid', 'faces', 'nuc']>
>>>o1=f['centroid'] 
<HDF5 dataset "centroid": shape (3, 4240), type "<f8">
>>>o1[:,0]
array([ -387.82973928,   533.54789111, -7359.64917621])
>>>o3=f['nuc']
<HDF5 dataset "nuc": shape (1, 4240), type "|O">
>>>type(o3)
<class 'h5py._hl.dataset.Dataset'>
>>>type(o3[0])
<class 'numpy.ndarray'>
>>>type(o3[0][0])
<class 'h5py.h5r.Reference'>
>>>o3[0][0]
<HDF5 object reference>
>>>o3[0]
array([<HDF5 object reference>, <HDF5 object reference>,
   <HDF5 object reference>, ..., <HDF5 object reference>,
   <HDF5 object reference>, <HDF5 object reference>], dtype=object)

我尝试了所有选项,但看不到 nuc 变量的数值。任何建议将不胜感激。

感谢大家的评论。以下命令现在正在工作。

 >>> f[f['nuc'][0][0]][:]
   array([[ -733.94435313,  -733.66995189,  -734.09632262, ...,
     -733.66832197,  -733.81233202,  -733.54615564],
   [  247.76823184,   247.49908481,   248.17514583, ...,
      240.16088783,   240.56909865,   240.84810507],
   [-7485.86866961, -7485.92114207, -7485.93468626, ...,
    -7508.16909395, -7508.16306386, -7508.20712349]])
 >>> f[f['nuc'][0][0]][:].shape
    (3, 1512)
 >>> f[f['nuc'][0][1]][:].shape
    (3, 1491)
 >>> f[f['nuc'][0][2]][:].shape
    (3, 1556)

【问题讨论】:

  • 不完全是您正在寻找的答案,但我使用 : scipy.io 模块,或者特别是 scipy.io.loadmat('my_mat.mat') 文件。返回包含值的字典。
  • 我知道这个模块,但如果大小小于 2GB,它就可以工作。在我的情况下,单元格变量中的数据是大矩阵。这使得大小超过 2 GB。
  • io.loadmat 从 MATLAB 单元创建对象 dtype 数组。但是h5py 不处理对象 dtype 数组。因此,从 MATLAB 引用到 HDF5 到 numpy 的映射变得更加复杂。

标签: python matlab cell-array h5py


【解决方案1】:

.mat 使用 -v7.3 标志(HDF5 格式)保存的文件使用使用“对象引用”的复杂数据模式。对象引用不是数据,而是指向数据的指针(在不同的位置)。 您使用对象引用来获取数据(在您的示例中为 nuc 值)。 您可以像这样获取nuc 的第一个元素的数据:
arr = f[ f['nuc'][0][0] ][:]arr = f[ o3[0][0] ][:]
(如果您愿意,也可以使用逗号分隔符:f[ f['nuc'][0,0] ][:]

解构上面的表达式:
f['nuc'] --> 是数据的字段(列)
f['nuc'][0] --> 是列中的第一个元素(对象引用的数组)
f['nuc'][0][0] --> 是数组中的第一个对象引用
f[ f['nuc'][0][0] ][:] --> 解引用对象引用并读取数据,即读取数组
或者,您可以这样做(为了便于阅读,我更喜欢这种方法):
obj_ref = f['nuc'][0][0] --> 返回第一个对象引用
f[obj_ref][:] --> 取消引用对象引用并读取数组数据

此 SO Q&A 提供了有关读取 .mat 文件的基本说明:
read-matlab-v7-3-file-into-python-list-of-numpy-arrays-via-h5py

我写了一个更完整的解释(用于阅读 SVHN 数据集)。你可以在这里访问它:
what-is-the-difference-between-the-two-ways-of-accessing-the-hdf5-group-in-svhn

【讨论】:

  • 非常感谢。以下命令在我的情况下有效。 f[f['nuc'][0][0]][:]
  • Ankit,不错。作为对象引用,f['nuc'][0][0] 在文件中定义了组或数据集的路径——类似于 ['group_name/dataset_name']。我用更正更新了我的帖子。
猜你喜欢
  • 2017-12-25
  • 2015-07-03
  • 2019-08-16
  • 1970-01-01
  • 2018-02-13
  • 1970-01-01
  • 1970-01-01
  • 2012-09-09
  • 2022-01-22
相关资源
最近更新 更多