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

21 投票
1 回答
9828 浏览
提问于 2025-04-17 19:42

我有一个从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')])}

我想访问类型为“cStream”的“futureDS”对象,但似乎无法通过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 个回答

16

很遗憾,SciPy不支持包含新式类对象的mat文件(这些类是用classdef定义的),而且我知道的第三方mat文件读取器也不支持。返回的mat字典中的__function_workspace__元素包含了你想要的信息,但这个方式没有文档说明,也还没有被逆向工程。

最简单的解决办法是在Matlab中把你的自定义类转换成基本的struct对象,然后再保存到磁盘。你可以通过简单地调用struct(futureDS)来实现这个转换(虽然会有警告)。这样做会把所有公共和私有属性都变成普通字段,任何靠谱的第三方读取器都能读取这些字段。

(更技术性一点,Matlab把这些对象保存为类型id为17的Matlab数组;官方文档(PDF)只列出了到15的类型。)

撰写回答