我知道两种解决方案(如果*.mat
文件非常大或非常深,我制作的其中一种效果更好)可以抽象出您与h5py
库的直接交互。
- 该
hdf5storage
软件包维护良好,旨在帮助将 v7.3 保存的 matfile 加载到 Python 中
- 我自己的 matfile 加载器,我写它是为了克服某些问题,即使最新版本 (
0.2.0
)hdf5storage
已经加载了大 (~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
将它们转换为numpy
具有各种 dtype 存储字段的对象数组。
我还注意到,数组的索引行为与您对 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 分钟)。