如何使scipy.loadmat()保留复数类型与MATLAB原始存储类?
解决SciPy加载MATLAB复数矩阵同时保留原始类型的问题
问题根源
当设置matlab_compatible=True时,scipy.io.loadmat会强制开启mat_dtype=True,这会严格遵循MATLAB到NumPy的类型映射,但此模式下复数数组会被错误截断为实数组(丢失虚部);而关闭mat_dtype(设为False)虽能正确加载复数,但会自动缩小非复数数组的存储类型(比如MATLAB的int32可能被转为int16)。
可行解决方案
方法一:两次加载合并结果
先以matlab_compatible=True加载保留原始类型的非复数数组,再以mat_dtype=False加载正确的复数数组,最后合并替换:
import scipy.io as sio import numpy as np # 第一次加载:保留所有变量的原始存储类型,但复数仅存实部 data_raw = sio.loadmat("your_file.mat", matlab_compatible=True) # 第二次加载:正确获取复数,非复数类型可能被压缩 data_complex = sio.loadmat("your_file.mat", mat_dtype=False) # 遍历替换复数数组 for key in data_raw: # 仅替换那些在第二次加载中是复数、第一次加载中是实数的变量 if isinstance(data_complex[key], np.ndarray) and np.iscomplexobj(data_complex[key]) and not np.iscomplexobj(data_raw[key]): data_raw[key] = data_complex[key] # data_raw 即为同时保留原始类型和完整复数的结果
方法二:分变量类型加载
先通过whosmat获取所有变量的类型,分别加载非复数(保留原始类型)和复数(正确加载)变量,再合并:
import scipy.io as sio # 获取MAT文件中所有变量的名称和类型 all_vars = sio.whosmat("your_file.mat") # 分离复数变量与非复数变量 complex_var_names = [var[0] for var in all_vars if var[1] == "complex128"] non_complex_var_names = [var[0] for var in all_vars if var[1] != "complex128"] # 加载非复数变量,保留原始类型 data_non_complex = sio.loadmat("your_file.mat", matlab_compatible=True, variable_names=non_complex_var_names) # 加载复数变量,确保完整加载虚部 data_complex = sio.loadmat("your_file.mat", mat_dtype=False, variable_names=complex_var_names) # 合并两个字典得到最终结果 data_final = {**data_non_complex, **data_complex}
注意事项
- 如果MATLAB中的复数数组是
complex64而非complex128,需调整方法二中的类型判断条件 - 方法二无需加载整个文件两次,性能更优,适合大文件场景
内容的提问来源于stack exchange,提问作者seairth
相关产品推荐
相关产品推荐

