【问题标题】:Read a matlab .mat file using h5py使用 h5py 读取 matlab .mat 文件
【发布时间】:2021-02-23 04:19:55
【问题描述】:

我想使用 Python3 包 h5py 读取 7.3 版本的 matlab .mat 文件。

它包含一个matlab中的变量,名为results

里面包含一个1*1的cell,里面struct里面的值就是我需要的。

在matlab中,我可以通过以下代码获取这些数据:

load('.mat PATH');
results{1}.res

我应该如何在 h5py 中读取这些数据? 示例.mat文件可以从here获取

【问题讨论】:

    标签: matlab numpy hdf5 h5py


    【解决方案1】:

    虽然 h5py 可以从 MATLAB 读取 h5 文件,但要弄清楚其中的内容需要一些探索 - 查看 keys groupsdatasets(可能还有 attr)。 scipy 中没有任何内容可以帮助您(scipy.io.loadmat 用于旧的 MATLAB mat 格式)。

    使用下载的文件:

    In [61]: f = h5py.File('Downloads/Basketball_ECO_HC.mat','r')
    In [62]: f
    Out[62]: <HDF5 file "Basketball_ECO_HC.mat" (mode r)>
    In [63]: f.keys()
    Out[63]: <KeysViewHDF5 ['#refs#', 'results']>
    In [65]: f['results']
    Out[65]: <HDF5 dataset "results": shape (1, 1), type "|O">
    In [66]: arr = f['results'][:]
    In [67]: arr
    Out[67]: array([[<HDF5 object reference>]], dtype=object)
    In [68]: arr.item()
    Out[68]: <HDF5 object reference>
    

    我必须检查h5py 文档,看看是否可以进一步检查该对象引用。我不熟悉。

    但探索其他key

    In [69]: list(f.keys())[0]
    Out[69]: '#refs#'
    In [70]: f[list(f.keys())[0]]
    Out[70]: <HDF5 group "/#refs#" (2 members)>
    In [71]: f[list(f.keys())[0]].keys()
    Out[71]: <KeysViewHDF5 ['a', 'b']>
    In [72]: f[list(f.keys())[0]]['a']
    Out[72]: <HDF5 dataset "a": shape (2,), type "<u8">
    In [73]: _[:]
    Out[73]: array([0, 0], dtype=uint64)
    In [74]: f[list(f.keys())[0]]['b']
    Out[74]: <HDF5 group "/#refs#/b" (7 members)>
    In [75]: f[list(f.keys())[0]]['b'].keys()
    Out[75]: <KeysViewHDF5 ['annoBegin', 'fps', 'fps_no_ftr', 'len', 'res', 'startFrame', 'type']>
    In [76]: f[list(f.keys())[0]]['b']['fps']
    Out[76]: <HDF5 dataset "fps": shape (1, 1), type "<f8">
    In [77]: f[list(f.keys())[0]]['b']['fps'][:]
    Out[77]: array([[22.36617883]])
    

    在 OS shell 中,我可以使用h5dump 查看文件。由此看来,res 数据集的数据最多。数据集也有属性。这可能是获得概览的更好方法,并使用它来指导 h5py 加载。

    In [80]: f[list(f.keys())[0]]['b']['res'][:]
    Out[80]: 
    array([[198., 196., 195., ..., 330., 328., 326.],
           [214., 214., 216., ..., 197., 196., 192.],
           [ 34.,  34.,  34., ...,  34.,  34.,  34.],
           [ 81.,  81.,  81., ...,  81.,  80.,  80.]])
    In [81]: f[list(f.keys())[0]]['b']['res'][:].shape
    Out[81]: (4, 725)
    In [82]: f[list(f.keys())[0]]['b']['res'][:].dtype
    Out[82]: dtype('<f8')
    

    【讨论】:

      【解决方案2】:

      如果您的问题一般是询问如何在 Python 中读取使用 v7.3 保存的 matfile,hdf5storage 包提供了一些可能对您有用的实用程序。对于您的文件(安装软件包后),您将运行

      In [0]: import hdf5storage as hdf5
      In [1]: pyIn = LoadMatFile('Basketball_ECO_HC.mat')
      In [2]: type(pyIn)                                                                                                                                             
      Out[2]: dict
      In [3]: pyIn.keys()                                                                                                                                             
      Out[3]: dict_keys(['results'])
      In [4]: type(pyIn['results'])                                                                                                                                   
      Out[4]: numpy.ndarray
      In [5]: pyIn['results'].shape                                                                                                                                   
      Out[5]: (1, 1)
      In [6]: pyIn['results'].dtype                                                                                                                                   
      Out[6]: dtype('O')
      In [7]: pyIn['results'][0,0].dtype                                                                                                                              
      Out[7]: dtype([('type', '<U4', (1, 1)), ('res', '<f8', (725, 4)), ('fps', '<f8', (1, 1)), ('fps_no_ftr', '<f8', (1, 1)), ('len', '<f8', (1, 1)), ('annoBegin', '<f8', (1, 1)), ('startFrame', '<f8', (1, 1))])
      

      您可以看到它在解析输入数组方面做得很好,尽管它可以将您在 Matlab 中使用 results{1}{1} 访问的单元格中的单元格折叠成您使用 @ 访问的二维 numpy 数组987654324@ 代替。我遇到的另一个奇怪的事情是在更深的结构字段中添加了一个维度,如下所示:

      In [8]: pyIn['results'][0,0]['res'].shape                                                                                        
      Out[8]: (1, 725, 4)
      In [9]: pyIn['results'][0,0]['res'][0,0,:]                                                                                                                      
      Out[9]: array([198., 214.,  34.,  81.])
      

      不完全确定为什么会发生这种情况,但总的来说应该可以正常工作。

      也就是说,我确实遇到了这个软件包的最新版本 (0.2) 的问题,对于真正深的数组/单元格/结构组合,它变​​得异常缓慢。好消息是该软件包仍在维护中,因此可能正在对此进行修复。尽管如此,这促使我为 matfiles 编写自己的 h5py 阅读器,这在这些情况下更快,我将作为另一个答案讨论它。

      【讨论】:

        【解决方案3】:

        正如我在关于 hd5fstorage 包的另一篇文章中提到的,我遇到了加载深度数组时速度太慢的问题。所以我实现了my own matfile loader,如果您关心如何将 v7.3 matfile 读入 Python 工作的细节,它的代码也可能更有用(因为它很紧凑)。 (也就是说,代码目前只有很少的 cmets,所以可能没那么有用。)

        对于我的库,输出与hdf5storage 非常相似,如下所示。

        In [0]: from MatFileMethods import LoadMatFile
        In [1]: pyIn = LoadMatFile('/Users/emilio/Downloads/Basketball_ECO_HC.mat')
        In [2]: type(pyIn)
        Out[2]: dict
        In [3]: pyIn.keys()
        Out[3]: dict_keys(['results'])
        In [4]: type(pyIn['results'])
        Out[4]: numpy.ndarray
        In [5]: pyIn['results'].shape
        Out[5]: (1, 1)
        

        请注意,与hdf5storage 包一样,Matlab 中使用results{1}{1} 调用的cell-within-a-cell 变成了使用pyIn['results'][0,0] 调用的二维numpy.ndarray,如下所示。

        In [6]: type(pyIn['results'][0,0])
        Out[6]: dict
        In [7]: pyIn['results'][0,0].keys()
        Out[7]: dict_keys(['annoBegin', 'fps', 'fps_no_ftr', 'len', 'res', 'startFrame', 'type'])
        In [8]: pyIn['results'][0,0]['res'].shape
        Out[8]: (725, 4)
        In [9]: pyIn['results'][0,0]['res'][0,:]
        Out[9]: array([198., 214.,  34.,  81.])
        

        hdf5storage 相比,我选择将Matlab 结构制作成Python dicts,这样结构的字段就是字典的键。

        在任何情况下,这个模块都没有经过全面测试,但对于加载 ~500Mb 和 hdf5storage 版本 0.2 似乎无法处理的更大 mat 文件(我的自己的装载机与hdf5storage 的 >10 分钟加载时间(它在 10 分钟时还没有完成加载))。 (我会注意到,与 Matlab 自己的

        【讨论】:

          猜你喜欢
          • 2019-07-06
          • 1970-01-01
          • 2016-01-25
          • 2013-10-19
          • 2015-07-03
          • 1970-01-01
          • 1970-01-01
          • 2017-04-23
          • 2014-12-01
          相关资源
          最近更新 更多