ChatGPT解决这个技术问题 Extra ChatGPT

在 Python 中读取 .mat 文件

是否可以在 Python 中读取二进制 MATLAB .mat 文件?

我已经看到 SciPy 声称支持读取 .mat 文件,但我没有成功。我安装了 SciPy 0.7.0 版,但找不到 loadmat() 方法。


u
user8408080

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

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

scipy 不支持 v7.3 mat-files(见注释 here)。解决方法见answer by vikrantt
但是,您可以将 mat 文件保存为早期版本。请参阅:mathworks.com/help/matlab/import_export/mat-file-versions.html(标题:“保存到非默认 MAT 文件版本”)
例如save('myfile.mat','-v7')
更新了 SciPy.io 教程的链接 docs.scipy.org/doc/scipy/tutorial/io.html @FranckDernoncourt
P
Peter Mortensen

scipy.io.savematscipy.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

如果您在保存数据时使用 Matlab 中的“-v7.3”标志,这可以正常工作。使用默认的 save(至少在 Matlab R2014b 中)会导致无法使用上述技术读取的文件。如果您确实使用了“-v7.3”标志,则可以很好地读取数字数据。
是的,这就是我在帖子中所说的。在 Matlab 中保存时需要使用 -v7.3。无论如何,您都应该这样做,因为它使用更好/更受支持/标准化的格式。
您能否解释一下您的示例中 f 和 data 之间的关系是什么?如何将 f 移动到 numpy 数组?
我怎么知道它包含 data/variable1 下的数据?
@devSpartan f.keys() 将向您展示您可以访问的内容
P
Peter Mortensen

首先将 .mat 文件另存为:

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

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

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

P
Peter Mortensen

有一个名为 mat4py 的不错的软件包,可以使用它轻松安装

pip install mat4py

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

从 MAT 文件加载数据

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

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

from mat4py import loadmat

data = loadmat('datafile.mat')

变量 data 是一个 dict,其变量和值包含在 MAT 文件中。

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

可以使用函数 savemat 将 Python 数据保存到 MAT 文件中。数据的结构必须与 loadmat 相同,即它应该由简单的数据类型组成,例如 dictliststrintfloat

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

from mat4py import savemat

savemat('datafile.mat', data)

参数 data 应为带有变量的 dict


请注意,mat4py 为您提供了一个类似 json 的字典、列表、列表列表树……——根本没有 numpy。 (mat4py/cmd.py my.mat 写入 my.json,1 长行。)
@denis:是的,上面也说过。但确实是一个好点:我通常喜欢这种结构,例如在网络应用程序中作为 numpy arrays are not JSON serializable
遇到:mat4py.loadmat.ParseError: Can only read from Matlab level 5 MAT-files
@s2t2:以前从未遇到过这个问题。您使用的是哪个 matlab 版本和哪个 scipy 版本?
ParseError:意外的字段名称长度:43
P
Peter Mortensen

安装 MATLAB 2014b 或更新版本后,可以使用 MATLAB engine for Python

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

我收到此错误:ModuleNotFoundError:没有名为“pylab”的模块。
尝试此答案时出现错误?这很奇怪,它不使用 pylab。
作为记录,此答案需要有效的 Matlab 安装和许可证 - 它在后台运行 Matlab 以完成读取。并且您获得项目的格式可能存在限制,需要进一步工作以使其具有可读性。例如,Simulink.Bus 对象以“matlab 对象”的形式出现,必须进一步处理,如果您想提取 Bus Element 对象,则会出现问题。
P
Peter Mortensen

读取文件

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

检查 MAT 变量的类型

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

字典中的键是 MATLAB 变量,值是分配给这些变量的对象。


p
panter

这个任务有一个很棒的库,叫做:pymatreader

只需执行以下操作:

安装包: pip install pymatreader 导入这个包的相关函数: from pymatreader import read_mat 使用函数读取matlab struct: data = read_mat('matlab_struct.mat') 使用data.keys() 定位数据在哪里实际存储。

键通常看起来像:dict_keys(['__header__', '__version__', '__globals__', 'data_opp'])。其中 data_opp 将是存储数据的实际键。这个键的名字当然可以在不同的文件之间改变。

最后一步 - 创建你的数据框: my_df = pd.DataFrame(data['data_opp'])

而已 :)


它做得更好的两件事是:它保留了 mat 对象的尺寸,并且加载的对象在 NumPy 数组中。谢谢
我很高兴它有帮助:)
P
Peter Mortensen

还有 MathWorks 本身的 MATLAB Engine for Python。如果您有 MATLAB,这可能值得考虑(我自己没有尝试过,但它的功能远不止读取 MATLAB 文件)。但是,我不知道是否允许将其分发给其他用户(如果这些人有 MATLAB,这可能不是问题。否则,也许 NumPy 是正确的方法?)。

此外,如果您想自己完成所有基本操作,MathWorks provides(如果链接更改,请尝试在 Google 上搜索 matfile_format.pdf 或其标题 MAT-FILE Format)有关文件格式结构的详细文档。它并不像我个人认为的那么复杂,但显然,这不是最简单的方法。它还取决于您想要支持的 .mat 文件的功能数量。

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

首先阅读文档。

使用十六进制编辑器(例如 HxD)并查看要解析的参考 .mat 文件。

尝试通过将字节保存到 .txt 文件并注释每一行来找出每个字节的含义。

使用类来保存每个数据元素(例如 miCOMPRESSED、miMATRIX、mxDOUBLE 或 miINT32)

.mat-files 的结构最适合将数据元素保存在树数据结构中;每个节点都有一个类和子节点


这是 mathworks 提供的某种疯狂的文档。 40 页解释格式,但没有提到它是 HDF5 的子集。
A
ASE

将 mat 文件读取到具有混合数据类型的 pandas dataFrame

import scipy.io as sio
mat=sio.loadmat('file.mat')# load mat-file
mdata = mat['myVar']  # variable in mat file 
ndata = {n: mdata[n][0,0] for n in mdata.dtype.names}
Columns = [n for n, v in ndata.items() if v.size == 1]
d=dict((c, ndata[c][0]) for c in Columns)
df=pd.DataFrame.from_dict(d)
display(df)

M
MrCrHaM

除了 scipy.io.loadmat 用于 v4(1.0 级)、v6、v7 到 7.2 的 matfile 和 h5py.File 用于 7.3 格式的 matfile 之外,还有另一种类型的 matfile 以 文本数据格式 代替二进制,通常创建Octave,其中 can't even be read in MATLAB

scipy.io.loadmath5py.File 都无法加载它们(在 scipy 1.5.3 和 h5py 3.1.0 上测试),我找到的唯一解决方案是 numpy.loadtxt

import numpy as np
mat = np.loadtxt('xxx.mat')

至少对于使用 MATLAB 生成的 .mat 文件,这将导致 UnicodeDecodeError
@emilaz 这是预期的。 np.loadtxt 仅适用于 Octave 生成的 .mat 个文件。
是的,我只是把它放在那里,以澄清未来的人看这个:)
S
Sameer Gadekar
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 文件。


N
Nannigalaxy

也可以使用 hdf5storage 库。有关 matlab 版本支持的详细信息,请参阅官方文档 here

import hdf5storage

label_file = "./LabelTrain.mat"
out = hdf5storage.loadmat(label_file) 

print(type(out)) # <class 'dict'>