在Python中读取.mat文件


Answers:


517

需要导入,import scipy.io...

import scipy.io
mat = scipy.io.loadmat('file.mat')


18
scipy不支持v7.3素材文件(请参阅此处的注释)。请参阅vikrantt答案以获取解决方案。
texnic 2014年

但是,您可以将Mat文件另存为早期版本。请参阅:mathworks.com/help/matlab/import_export/mat-file-versions.html(标题:“保存
为非

5
例如save('myfile.mat','-v7')
watsonic

149

无论是scipy.io.savemat,还是scipy.io.loadmat对于MATLAB阵列的7.3版本的工作。但是好消息是MATLAB版本7.3文件是hdf5数据集。因此,可以使用许多工具(包括NumPy)读取它们。

对于Python,您将需要h5py扩展,该扩展在系统上需要HDF5。

import numpy as np
import h5py
f = h5py.File('somefile.mat','r')
data = f.get('data/variable1')
data = np.array(data) # For converting to a NumPy array

6
如果在保存数据时在Matlab中使用'-v7.3'标志,则此方法效果很好。使用默认设置save(至少在Matlab R2014b中使用)会导致文件无法使用上述技术读取。如果确实使用“ -v7.3”标志,则可以很好地读取数字数据。
Chipaudette

3
是的,这就是我在帖子中所说的。在Matlab中保存时需要使用-v7.3。无论如何,您都应该这样做,因为它使用更好/更受支持/标准化的格式。
维克兰特2015年

4
您能否解释一下示例中f数据之间的关系?如何将f移动到numpy数组?
heracho

在提示符下使用以下命令保存变量:save('filename', '-v7.3', 'var1');
Kevin Katzke

23

首先将.mat文件另存为:

save('test.mat', '-v7')

之后,在Python中,使用通常的loadmat函数:

import scipy.io as sio
test = sio.loadmat('test.mat')

15

有一个很好的软件包mat4py,可以很容易地使用安装

pip install mat4py

使用起来很简单(从网站上):

从MAT文件加载数据

该函数loadmat仅使用Python dictlist对象将MAT文件中存储的所有变量加载到简单的Python数据结构中。数字和单元格数组将转换为按行排序的嵌套列表。压缩数组以消除仅包含一个元素的数组。结果数据结构由与JSON格式兼容的简单类型组成。

示例:将MAT文件加载到Python数据结构中:

from mat4py import loadmat

data = loadmat('datafile.mat')

变量datadict带有MAT文件中包含的变量和值的a 。

将Python数据结构保存到MAT文件

可以使用函数将Python数据保存到MAT文件中savemat。数据已经以同样的方式为被结构化的loadmat,也就是说,它应该由简单数据类型,像dictliststrint,和float

示例:将Python数据结构保存到MAT文件中:

from mat4py import savemat

savemat('datafile.mat', data)

参数data应为dict带有变量的a。


请注意,mat4py为您提供了类似json,字典,列表,列表列表的树...-根本没有numpy。(mat4py/cmd.py my.mat写的my.json是1行)
。–丹尼斯

1
@denis:是的,上面也有提到。但是确实有一个好处:我通常喜欢这种结构,例如在Web应用程序中,因为numpy数组不是JSON可序列化的
克莱布(Cleb)

遇到:mat4py.loadmat.ParseError: Can only read from Matlab level 5 MAT-files
s2t2,19年

@ s2t2:以前从未遇到过此问题。您使用的是哪个Matlab版本和哪个scipy版本?
克莱布(Cleb)

ParseError:意外的字段名称长度:43
Aleksejs Fomins

13

安装了MATLAB 2014b或更高版本后,可以使用适用于PythonMATLAB引擎

import matlab.engine
eng = matlab.engine.start_matlab()
content = eng.load("example.mat", nargout=1)

我收到此错误:ModuleNotFoundError:没有名为“ pylab”的模块。
下雨

3
尝试此答案时出现错误?奇怪的是,它不使用pylab。
丹尼尔(Daniel)

11

读取文件

import scipy.io
mat = scipy.io.loadmat(file_name)

检查MAT变量的类型

print(type(mat))
#OUTPUT - <class 'dict'>

字典中的MATLAB变量分配给这些变量对象


7

MathWorks本身也提供用于PythonMATLAB引擎。如果您有MATLAB,则可能值得考虑(我自己还没有尝试过,但是它具有比仅读取MATLAB文件更多的功能)。但是,我不知道是否允许将其分发给其他用户(如果这些人拥有MATLAB,这可能不是问题。否则,也许NumPy是正确的选择?)。

另外,如果您想自己掌握所有基础知识,MathWorks将提供有关文件格式结构的详细文档(如果链接发生更改,请尝试使用google matfile_format.pdf或其标题MAT-FILE Format)。它并不像我个人想象的那样复杂,但是显然,这不是最简单的方法。它还取决于.mat您要支持-files的多少功能。

我编写了一个“小”(约700行)Python脚本,该脚本可以读取一些基本的.mat-files。我既不是Python专家,也不是初学者,我花了大约两天时间来编写它(使用上面链接的MathWorks文档)。我学到很多新东西,这很有趣(大部分时间)。当我在工作时编写Python脚本时,恐怕我无法发布它了……但是我可以在这里给出一些建议:

  • 首先阅读文档。
  • 使用十六进制编辑器(例如HxD)并查看.mat要解析的参考文件。
  • 尝试通过将字节保存到.txt文件并注释每行来弄清楚每个字节的含义。
  • 使用类来保存每个数据元素(如miCOMPRESSEDmiMATRIXmxDOUBLE,或miINT32
  • .mat-files'结构是最佳的用于保存在一个树形数据结构中的数据元素; 每个节点都有一个类和子节点

9
那是mathworks提供的某种疯狂的文档。共40页,对格式进行了解释,但没有提及它是HDF5的子集。
丹尼尔(Daniel)

-1
from os.path import dirname, join as pjoin
import scipy.io as sio
data_dir = pjoin(dirname(sio.__file__), 'matlab', 'tests', 'data')
mat_fname = pjoin(data_dir, 'testdouble_7.4_GLNX86.mat')
mat_contents = sio.loadmat(mat_fname)

您可以使用上面的代码在Python中读取默认保存的.mat文件。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.