我知道两种解决方案(其中一种是我自己制作的,如果*.mat
文件非常大或非常深,则效果更好),可以抽象出您与h5py
库的直接交互。
hdf5storage
包,它得到了很好的维护,并旨在帮助将v7.3保存的mat文件加载到Python中
- 我的自己的mat文件加载器,我编写它来克服即使最新版本(
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字典,其键是结构的字段,而将它们转换为具有各种数据类型存储字段的numpy
对象数组。
我还注意到数组的索引行为与您从Matlab方法中期望的不同。具体来说,在Matlab中,为了获取第二个结构的name
字段,您将对structure进行索引:
[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 mat文件。最后需要指出的是,在处理大于500MB的文件时,我发现hdf5storage
包在加载时会卡住,而我的包则不会(尽管仍需花费约1.5分钟完成加载)。