我知道两种解决方案(如果*.mat 文件非常大或非常深,我制作的其中一种效果更好)可以抽象出您与h5py 库的直接交互。
-
hdf5storage 包,维护良好,旨在帮助将 v7.3 保存的 matfile 加载到 Python 中
-
my own matfile loader,我写它是为了克服某些问题,即使
hdf5storage 的最新版本 (0.2.0) 已经加载了大 (~500Mb) 和/或深数组(我实际上不确定这两者中的哪一个导致问题)
假设您已将这两个包下载到可以将它们加载到 Python 中的位置,您可以看到它们为您的示例 'test.mat' 产生了相似的输出:
In [1]: pyInMine = LoadMatFile('test.mat')
In [2]: pyInHdf5 = hdf5.loadmat('test.mat')
In [3]: pyInMine()
Out[3]: dict_keys(['struArray'])
In [4]: pyInMine['struArray'].keys()
Out[4]: dict_keys(['data', 'id', 'name'])
In [5]: pyInHdf5.keys()
Out[5]: dict_keys(['struArray'])
In [6]: pyInHdf5['struArray'].dtype
Out[6]: dtype([('name', 'O'), ('id', '<f8', (1, 1)), ('data', 'O')])
In [7]: pyInHdf5['struArray']['data']
Out[7 ]:
array([[array([[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]]),
array([[3., 4., 5., 6., 7., 8., 9.]]), array([[0.]])]],
dtype=object)
In [8]: pyInMine['struArray']['data']
Out[8]:
array([[array([[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]]),
array([[3., 4., 5., 6., 7., 8., 9.]]), array([[0.]])]],
dtype=object)
最大的不同是我的库将 Matlab 中的结构数组转换为 Python 字典,其键是结构的字段,而 hdf5storage 将它们转换为具有各种 dtype 存储字段的 numpy 对象数组。
我还注意到,数组的索引行为与您对 Matlab 方法的期望不同。具体来说,在 Matlab 中,为了获得第二个结构的 name 字段,您需要索引 结构:
[Matlab] >> struArray(2).name`
[Matlab] >> 'two'
在我的包中,你必须首先抓取字段,然后然后索引:
In [9]: pyInMine['struArray'].shape
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-64-a2f85945642b> in <module>
----> 1 pyInMine['struArray'].shape
AttributeError: 'dict' object has no attribute 'shape'
In [10]: pyInMine['struArray']['name'].shape
Out[10]: (1, 3)
In [11]: pyInMine['struArray']['name'][0,1]
Out[11]: 'two'
hdf5storage 包稍微好一点,它允许您索引结构然后抓取字段,反之亦然,因为结构化的 numpy 对象数组是如何工作的:
In [12]: pyInHdf5['struArray'].shape
Out[12]: (1, 3)
In [13]: pyInHdf5['struArray'][0,1]['name']
Out[13]: array([['two']], dtype='<U3')
In [14]: pyInHdf5['struArray']['name'].shape
Out[14]: (1, 3)
In [15]: pyInHdf5['struArray']['name'][0,1]
Out[15]: array([['two']], dtype='<U3')
同样,这两个包对最终输出的处理略有不同,但总的来说,两者都非常擅长读取 v7.3 matfiles。最后的想法是,在大约 500MB+ 文件的情况下,我发现 hdf5storage 包在加载时挂起,而我的包没有(尽管完成加载仍然需要大约 1.5 分钟)。