Scipy.io savemat/loadmat处理嵌套列表时的格式异常问题
解决scipy savemat/loadmat后嵌套列表格式异常的问题
这问题我之前踩过坑!原因其实是MATLAB的.mat格式本身不支持Python里这种长度不规则的嵌套列表——MATLAB的数组要求所有子元素维度一致,所以当你用savemat存储这种每个子列表长度不一样的结构时,它会自动把这些子列表转成MATLAB的cell数组,等你用loadmat加载回来,就变成了嵌套的numpy array对象,而不是原来的纯Python列表。
快速修复方案
加载后遍历每个元素,把numpy array转换成普通Python列表就行,用列表推导式就能快速搞定:
from scipy.io import loadmat, savemat import numpy as np # 你的原保存代码 dic = {"X": [[1,2,3],[1,2,4],[6,7,8,9],[1]]} savemat('Test.mat', mdict=dic) # 加载并恢复格式 loaded_data = loadmat('Test.mat') # 注意loadmat返回的X会多一层外层嵌套,先取[0]拿到cell数组的内容 raw_x = loaded_data['X'][0] # 把每个二维array压平成一维再转列表 restored_x = [arr.flatten().tolist() for arr in raw_x] print(restored_x) # 输出:[[1, 2, 3], [1, 2, 4], [6, 7, 8, 9], [1]]
处理更深层次的嵌套
如果你的嵌套结构不止一层,比如[[[1,2], [3]], [4,5]]这种,那可以写个递归函数来处理所有层级的array转换:
def restore_py_list(mat_obj): result = [] for item in mat_obj: if isinstance(item, np.ndarray): # 把二维array压平成一维再转列表 result.append(item.flatten().tolist()) else: # 递归处理嵌套结构 result.append(restore_py_list(item)) return result # 使用示例 loaded_data = loadmat('Test.mat') restored_x = restore_py_list(loaded_data['X'][0])
额外说明
如果不是必须用.mat文件存储,其实可以考虑用Python原生的pickle或者JSON格式来保存数据,这样能直接保留Python的列表结构,不需要额外转换。但如果是要和MATLAB交互,那上述的转换方法就是最直接的解决方案。
内容的提问来源于stack exchange,提问作者tahsin314
相关产品推荐
相关产品推荐

