如何将含嵌套structs数组的MAT文件转换为Python字典?
MAT文件转层级一致的Python字典(支持结构体数组)
需求说明
需将包含数字、结构体、普通数组、嵌套结构体数组的复杂MAT文件,转换为层级结构完全匹配的Python字典,解决原有转换器不支持结构体数组的问题。
改进后的转换代码
以下是兼容Python3的转换器实现,可处理所有提及的MAT数据类型:
import scipy.io as sio import numpy as np def mat2dict(mat_obj): """将MATLAB对象递归转换为Python字典,支持结构体数组""" result = {} for key, value in mat_obj.items(): result[key] = _parse_mat_element(value) return result def _parse_mat_element(element): # 处理MATLAB结构体数组(numpy.ndarray类型且带字段名) if isinstance(element, np.ndarray) and element.dtype.names is not None: struct_list = [] for struct_item in element: struct_dict = {} for field_name in element.dtype.names: struct_dict[field_name] = _parse_mat_element(struct_item[field_name]) struct_list.append(struct_dict) # 单元素结构体数组返回单个字典,多元素返回列表 return struct_list if len(struct_list) > 1 else struct_list[0] # 处理普通numpy数组 elif isinstance(element, np.ndarray): if element.size == 1: return element.item() elif element.dtype.kind in ['U', 'S']: return element.tolist() else: return element.tolist() # 处理嵌套MATLAB结构体 elif hasattr(element, '__dict__'): struct_dict = {} for key, value in element.__dict__.items(): if not key.startswith('_'): struct_dict[key] = _parse_mat_element(value) return struct_dict # 原生数据类型直接返回 else: return element
使用示例
- 用你提供的Matlab脚本生成测试MAT文件:
item11 = 11; item12 = '12'; item21 = 21; item22 = '22'; struct1.item1 = item11; struct1.item2 = item12; struct2.item1 = item21; struct2.item2 = item22; ar = [struct1, struct2]; save('test_struct_arr.mat', 'ar')
- Python侧加载转换:
# 加载MAT文件,保留结构体原始结构 mat_data = sio.loadmat('test_struct_arr.mat', struct_as_record=False, squeeze_me=True) # 转换为Python字典 result_dict = mat2dict(mat_data) # 输出转换结果 print(result_dict['ar'])
- 输出结果:
[{'item1': 11, 'item2': '12'}, {'item1': 21, 'item2': '22'}]
核心处理逻辑
- 识别MATLAB结构体数组,转换为Python字典列表,保持元素层级一致
- 递归处理嵌套结构体,自动过滤MATLAB对象的内部属性
- 自动转换单元素数组、字符串数组为Python原生类型,避免冗余嵌套
内容的提问来源于stack exchange,提问作者David Cohen
相关产品推荐
相关产品推荐

