如何使用scipy.io.loadmat读取文件中的Matlab datetime
如何在Python中读取Matlab -v7文件中的datetime对象
首先得说清楚问题根源:Matlab的datetime属于MCOS(Matlab类对象系统)类型,而scipy.io.loadmat对这类对象的支持很有限,只能读取成MatlabOpaque这种难以直接使用的格式。下面给你几种实用的解决方案:
方法1:用pyreadmat库(推荐,无需安装Matlab)
pyreadmat是专门针对Matlab .mat文件的读取工具,比scipy更擅长处理嵌套结构和MCOS对象,包括datetime类型。
步骤如下:
- 先安装库:
pip install pyreadmat
- 读取并转换时间:
from pyreadmat import read_mat import datetime as dt # 读取文件,保留原始结构格式 mat_data = read_mat("myfilename.mat", struct_as_record=False) # 直接访问目标时间字段 mat_datetime = mat_data["mydata"]["sub1"]["time_utc"] # 如果返回的是Matlab的datenum数值,转成Python datetime # 注意Matlab和Python的日期基准差异:Matlab从0000-01-01开始,Python从公元1年1月1日开始 matlab_epoch = dt.datetime(0, 1, 1) python_epoch = dt.datetime(1, 1, 1) offset = python_epoch - matlab_epoch py_datetime = matlab_epoch + dt.timedelta(days=mat_datetime) - offset print(py_datetime) # 应该会输出:2018-01-31 09:25:52
要是pyreadmat直接返回了Python的datetime对象,那直接用就行,不用额外转换。
方法2:用Matlab Engine(需要安装Matlab)
如果你有Matlab的安装权限,直接通过Matlab引擎读取是最稳妥的,能完美转换时间格式:
- 先在Matlab命令行里安装引擎:
cd(fullfile(matlabroot, 'extern', 'engines', 'python')) system('python setup.py install')
- 在Python中调用引擎读取:
import matlab.engine import datetime as dt # 启动Matlab引擎 eng = matlab.engine.start_matlab() # 加载.mat文件 mat_data = eng.load("myfilename.mat", nargout=1) # 把Matlab datetime转成datenum数值 datenum_val = eng.datenum(mat_data["mydata"]["sub1"]["time_utc"]) # 转换为Python datetime,处理基准差异 matlab_epoch = dt.datetime(0, 1, 1) python_epoch = dt.datetime(1, 1, 1) offset = python_epoch - matlab_epoch py_datetime = matlab_epoch + dt.timedelta(days=datenum_val) - offset print(py_datetime) # 输出:2018-01-31 09:25:52 # 用完记得关闭引擎 eng.quit()
方法3:手动解析MatlabOpaque(不推荐,仅应急用)
如果只能用scipy,那只能硬着头皮解析MatlabOpaque里的arr数组。你拿到的array([3707764736, 2, 1, 1, 1, 1], dtype=uint32)中,第一个元素是Matlab datetime底层的纳秒级时间戳(基准一般是2000-01-01),可以这么转:
import datetime as dt # 从MatlabOpaque中取出数组 arr = matlabcontents['mydata'].__dict__['sub1'].__dict__['time_utc'].arr # 假设基准是2000-01-01,把纳秒转成微秒后计算时间 matlab_epoch = dt.datetime(2000, 1, 1) py_datetime = matlab_epoch + dt.timedelta(microseconds=arr[0]/1000) print(py_datetime)
注意:这种方法依赖Matlab版本和datetime的存储逻辑,可能不稳定,优先用前两种方法。
内容的提问来源于stack exchange,提问作者00__00__00
相关产品推荐
相关产品推荐

