使用Python打开.mat(Matlab数据)文件

5
我可以帮助您翻译如下内容,涉及IT技术:

我尝试从Python中导入和读取.mat文件,但是尝试了两种方法都没有成功。

方法1 (在Python中):

import scipy.io as sio    
mat = sio.loadmat('path/tmpPBworkspace.mat')

我得到的消息类似于:

{'None': MatlabOpaque([ (b'rateQualityOutTrim', b'MCOS', b'dataset', array([[3707764736],
        [         2],
        [         1],
        [         1],
        [         1],
        [         1]], dtype=uint32))],
              dtype=[('s0', 'O'), ('s1', 'O'), ('s2', 'O'), ('arr', 'O')]),
 '__function_workspace__': array([[ 0,  1, 73, ...,  0,  0,  0]], dtype=uint8),
 '__globals__': [],
 '__header__': b'MATLAB 5.0 MAT-file, Platform: GLNXA64, Created on: Thu May 10 07:11:52 2018',
 '__version__': '1.0'}

我不确定出了什么问题?我希望能看到一个数据框架。另外需要说明的是,在方法1中,我已经将.mat文件保存为与SciPy兼容的版本。
在Matlab中:
save('path/tmpPBworkspace.mat','rateQualityOutTrim','-v7')

还尝试了另一种方法:

方法2:h5py

在Matlab中:

save('path/tmpPBworkspaceH5.mat','rateQualityOutTrim','-v7.3')

在Python中:

import numpy as np
import h5py
f = h5py.File('/GAAR/ustr/projects/PBF/tmpPBworkspaceH5.mat','r')
data = f.get('rateQualityOutTrim/date')
data = np.array(data)

我明白了

f
Out[154]: <HDF5 file "tmpPBworkspaceH5.mat" (mode r)>

data
array(None, dtype=object)

数组为空。不确定如何在此处访问数据。


1
不透明项是Matlab类对象,无法转换为NumPy数组。 - hpaulj
什么是Matlab对象? - hpaulj
当我查看H5文件时,我必须系统地搜索数据组和数据集。h5dump可以提供快速概述。 - hpaulj
如果您真正掌握了Matlab部分,不要使用任何Matlab类对象,而是选择MATLAB数组、单元格和结构体(因为它们可以转换为numpy数组)。我并不太熟悉Matlab,但可能可以使用struct(your_class_object)进行转换。 - Nerxis
另一个选择是使用一种反向工程和解析__function_workspace__数据的方法(在使用scipy.io.loadmat后可以在字典中看到非常长的数组)-请查看此链接。但是,正如您所看到的,这不是一种很好的处理.mat文件的方式。 - Nerxis
显示剩余4条评论
2个回答

6
你可以使用 scipy.io.loadmat 来实现此功能:
from scipy import io

loaded = io.loadmat('/GAAR/ustr/projects/PBF/tmpPBworkspaceH5.mat')

loaded会是一个将名称映射到数组的字典。


但是,如果您控制Matlab部分和Pandas部分,使用csvwrite要容易得多:

In Matlab:

csvwrite('path/tmpPBworkspaceH5.csv','rateQualityOutTrim')

在Python中:

pd.read_csv('tmpPBworkspaceH5.csv')

谢谢Ami Tavory。我已经这样做了,但是我收到了与之前相似的消息{'None': MatlabOpaque([ (b'rateQualityOutTrim', b'MCOS', b'dataset', array([[3707764736], [ 2], [ 1], [ 1], [ 1], [ 1]], dtype=uint32))], dtype=[('s0', 'O'), ('s1', 'O'), ('s2', 'O'), ('arr', 'O')]), '__function_workspace__': array([[ 0, 1, 73, ..., 0, 0, 0]], dtype=uint8), '__globals__': [], '__header__': b'MATLAB 5.0 MAT-file, Platform: GLNXA64, Created on: Fri May 11 03:33:35 2018', '__version__': '1.0'} - SBad
我还不确定如何提取数据? - SBad
@SBad 知道了 - 这在 这个笔记本 中解释得非常好 - 它是用 Julia 编写的,但你可以跟着解释。 - Ami Tavory
顺便说一下,看了你的问题,似乎你也掌握了Matlab部分的内容。在这种情况下,有更简单的选择。我编辑了我的答案,包括其中一个选项。 - Ami Tavory
@SBad 这是一个很长的答案,因为这种格式实际上并不适合用于导出 - 它是反向工程的,并且您可能根本不想首先在其中编写。 - Ami Tavory
我有一个非常大的数据集(超过一百万行),导出为csv不是最优的选择,可能需要很长时间。我认为将数据保存为.mat格式并在Python中进行导入可能是最好的解决方案。 - SBad

0

我也会尝试使用scipy.io。

我有一个Matlab的“struct”(Auslage_000.mat),我理解它是一种嵌套字典。它有几个标头信息和三个数据通道(振动数据)。我还发现Spyder(Python开发环境)很有用,因为一旦加载了数据,您可以通过变量管理器访问数据(类似于Matlab)。

import scipy.io as sio
    
mat_contents = sio.loadmat('Auslage_000.mat',squeeze_me=True,struct_as_record=False)

当我检查变量“mat_contends”的输出时,我得到:
mat_contents

Out[14]: 
{'__header__': b'MATLAB 5.0 MAT-file, Platform: PCWIN, Created on 2019-08-14 13:14:56 by TiePie software (www.tiepie.com).',
 '__version__': '1.0',
 '__globals__': [],
 'tpd': <scipy.io.matlab.mio5_params.mat_struct at 0x1ea3441d438>}

我的实际数据在tpd中。我可以按以下方式进一步访问数据:

#Access the data via the key 'tpd' and then the attribute 'Data'
# -> Data is a numpy array with 3 channels (ch1, ch2, ch3) / dimensions
Data = mat_contents['tpd'].Data
    
# extract channel1 
    
ch1 = Data[0]

我猜你得先挖掘一下你的Matlab文件中的“键”和“属性”(如果它是一个结构体)。


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