是否可以在 Python 中读取二进制 MATLAB .mat 文件?
我已经看到 SciPy 声称支持读取 .mat 文件,但我没有成功。我安装了 SciPy 0.7.0 版,找不到loadmat()
方法。
需要导入,import scipy.io
...
import scipy.io
mat = scipy.io.loadmat('file.mat')
不适用于 MATLAB 数组 7.3 版scipy.io.savemat
。scipy.io.loadmat
但好的部分是 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
首先将 .mat 文件另存为:
save('test.mat', '-v7')
之后,在 Python 中,使用通常的loadmat
函数:
import scipy.io as sio
test = sio.loadmat('test.mat')
有一个很好的包叫做mat4py
它可以很容易地安装使用
pip install mat4py
使用起来很简单(来自网站):
从 MAT 文件加载数据
该函数仅使用 Python和对象loadmat
将存储在 MAT 文件中的所有变量加载到简单的 Python 数据结构中。数值和元胞数组将转换为按行排序的嵌套列表。数组被压缩以消除只有一个元素的数组。生成的数据结构由与JSON格式兼容的简单类型组成。dict
list
示例:将 MAT 文件加载到 Python 数据结构中:
from mat4py import loadmat
data = loadmat('datafile.mat')
该变量data
是dict
MAT 文件中包含的变量和值。
将 Python 数据结构保存到 MAT 文件
Python 数据可以使用savemat
. 数据的结构必须与 for 相同loadmat
,即它应该由简单的数据类型组成,如dict
、list
、str
、int
和float
。
示例:将 Python 数据结构保存到 MAT 文件:
from mat4py import savemat
savemat('datafile.mat', data)
参数data
应dict
与变量一起使用。
读取文件
import scipy.io
mat = scipy.io.loadmat(file_name)
检查 MAT 变量的类型
print(type(mat))
#OUTPUT - <class 'dict'>
字典中的键是MATLAB 变量,值是分配给这些变量的对象。
安装 MATLAB 2014b 或更新版本后,可以使用Python 的 MATLAB 引擎:
import matlab.engine
eng = matlab.engine.start_matlab()
content = eng.load("example.mat", nargout=1)
还有 MathWorks 本身的MATLAB Engine for Python。如果您有 MATLAB,这可能值得考虑(我自己没有尝试过,但它的功能远不止读取 MATLAB 文件)。但是,我不知道是否允许将其分发给其他用户(如果这些人有 MATLAB,这可能不是问题。否则,也许 NumPy 是正确的方法?)。
此外,如果您想自己完成所有基础知识,MathWorks 提供了(如果链接更改,请尝试 googlematfile_format.pdf
或其标题MAT-FILE Format
)有关文件格式结构的详细文档。它并不像我个人认为的那么复杂,但显然,这不是最简单的方法。它还取决于.mat
您想要支持的 -files 的多少功能。
我写了一个“小”(大约 700 行)Python 脚本,它可以读取一些基本.mat
的文件。我既不是 Python 专家也不是初学者,我花了大约两天时间来编写它(使用上面链接的 MathWorks 文档)。我学到了很多新东西,而且很有趣(大部分时间)。由于我在工作中编写了 Python 脚本,恐怕我无法发布它......但我可以在这里给出一些建议:
.mat
要解析的参考文件。miCOMPRESSED
、miMATRIX
、mxDOUBLE
或miINT32
).mat
结构最适合将数据元素保存在树数据结构中;每个节点都有一个类和子节点将 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)
这个任务有一个很棒的库,叫做:pymatreader
.
只需执行以下操作:
安装包:pip install pymatreader
导入这个包的相关功能:from pymatreader import read_mat
使用函数读取 matlab 结构:data = read_mat('matlab_struct.mat')
用于data.keys()
定位数据的实际存储位置。
dict_keys(['__header__', '__version__', '__globals__', 'data_opp'])
. data_opp
存储数据的实际密钥在哪里。这个键的名字当然可以在不同的文件之间改变。my_df = pd.DataFrame(data['data_opp'])
就是这样 :)
除了scipy.io.loadmat
用于 v4(1.0 级)、v6、v7 到 7.2 格式的 matfile 和 h5py.File
7.3 格式的 matfile,还有另一种类型的 matfile 是文本数据格式而不是二进制文件,通常由Octave创建,甚至无法在 MATLAB 中读取。
两者scipy.io.loadmat
都h5py.File
无法加载(在 scipy 1.5.3 和 h5py 3.1.0 上测试),我找到的唯一解决方案是numpy.loadtxt
.
import numpy as np
mat = np.loadtxt('xxx.mat')
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 文件。
也可以使用 hdf5storage 库。有关 matlab 版本支持的详细信息,请单击此处的官方文档。
import hdf5storage
label_file = "./LabelTrain.mat"
out = hdf5storage.loadmat(label_file)
print(type(out)) # <class 'dict'>