在Python中访问包含Matlab类的.mat文件

21

我有一个由 Matlab 2012b 生成的 .mat 文件,其中包含一个用户定义的 Matlab 类变量。

在 Python 3.3 中使用 scipy.io.loadmat 加载文件时,出现以下情况:

mat=scipy.io.loadmat('D:\test.mat')
mat
{'__header__': b'MATLAB 5.0 MAT-file, Platform: PCWIN64, Created on: Fri Feb 22 15:26:28 2013', '__function_workspace__': array([[ 0,  1, 73, ...,  0,  0,  0]], dtype=uint8), '__globals__': [], '__version__': '1.0', 'None': MatlabOpaque([ (b'futureDS', b'MCOS', b'cStream', [[3707764736], [2], [1], [1], [1], [1]])], 
      dtype=[('s0', 'O'), ('s1', 'O'), ('s2', 'O'), ('arr', 'O')])}

我希望能够访问“futureDS”类型为“cStream”的对象,但似乎无法使用mat ['None']实现。调用mat['None']只会导致以下结果:

MatlabOpaque([ (b'futureDS', b'MCOS', b'cStream', [[3707764736], [2], [1], [1], [1], [1]])], 
      dtype=[('s0', 'O'), ('s1', 'O'), ('s2', 'O'), ('arr', 'O')])

我陷入了困境。我是Python的新手,正在试图将以前的Matlab工作移植过来。非常感谢您提供任何帮助。

谢谢。

1个回答

15

遗憾的是,SciPy不支持包含新式类对象(使用classdef定义的那些)的mat文件,据我所知,任何第三方mat文件阅读器也不支持。在返回的mat字典中的__function_workspace__元素以某种未记录且尚未反向工程的方式包含了您需要的信息。

最简单的解决方案是在保存到磁盘之前在Matlab中将自定义类转换为基本的struct对象。这可以通过简单调用struct(futureDS)来实现(尽管会有一个警告)。它将所有公共和私有属性公开为普通字段,可以被任何值得其盐的第三方阅读器读取。

更技术上地说,Matlab使用类型ID 17保存这些对象;官方文档(PDF)仅枚举到15个类型。


8
附言:我已经成功地逆向工程了这种格式的大部分内容。请参阅此IJulia笔记本以获取详细信息。 - mbauman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接