求助:将MATLAB中含嵌套结构的复杂数据转CSV(用于Python读取)
解决方案:将嵌套MATLAB结构体转换为CSV文件
针对你提到的def.mat文件中1×42嵌套结构体转CSV的需求,提供两种实用方案:
方案一:用MATLAB预处理导出CSV
如果能访问MATLAB,直接在MATLAB中处理是最稳妥的方式,能完美兼容MATLAB原生结构体格式:
- 加载MAT文件并定义递归扁平化函数
load('def.mat'); % 加载文件,得到1×42的data结构体数组 % 递归扁平化嵌套结构体的函数 function flat_data = flatten_struct(s, prefix) flat_data = struct(); fields = fieldnames(s); for i = 1:length(fields) field = fields{i}; value = s.(field); new_prefix = [prefix, '_', field]; if isstruct(value) && ~isempty(value) % 递归处理嵌套结构体 nested_flat = flatten_struct(value, new_prefix); flat_data = merge_structs(flat_data, nested_flat); elseif iscell(value) % 将cell数组转为逗号分隔的字符串 flat_data.(new_prefix(2:end)) = strjoin(cellfun(@num2str, value, 'UniformOutput', false), ','); elseif isdouble(value) % 将多维double数组转为字符串(单值直接保留) if length(value) > 1 flat_data.(new_prefix(2:end)) = strjoin(num2str(value(:)), ','); else flat_data.(new_prefix(2:end)) = value; end else flat_data.(new_prefix(2:end)) = value; end end end % 合并两个结构体的辅助函数 function merged = merge_structs(s1, s2) merged = s1; fields = fieldnames(s2); for i = 1:length(fields) merged.(fields{i}) = s2.(fields{i}); end end
- 处理所有结构体元素并导出CSV
result_table = table(); for i = 1:length(data) flat_struct = flatten_struct(data(i), ''); row_table = struct2table(flat_struct); result_table = [result_table; row_table]; end writetable(result_table, 'output.csv');
注意:如果你的cell或嵌套结构体有特殊格式(比如cell内是嵌套结构体),可以根据实际需求修改flatten_struct里的处理逻辑。
方案二:用Python直接读取并转换
如果后续要在Python中处理,直接用Python读取MAT文件并转换更高效,无需依赖MATLAB:
- 先安装依赖包
pip install scipy pandas
- 编写转换代码
import scipy.io as sio import pandas as pd import numpy as np def flatten_struct(obj, prefix=''): flat_dict = {} # 处理MATLAB的1×1结构体数组 if isinstance(obj, np.ndarray) and obj.dtype.names: obj = obj.item() if obj.size == 1 else obj if isinstance(obj, np.ndarray): # 将多维数组转为逗号分隔的字符串(单值直接提取) if obj.size > 1: flat_dict[prefix] = ','.join(map(str, obj.flatten())) else: flat_dict[prefix] = obj.item() if obj.size else None elif isinstance(obj, dict): # 递归处理嵌套结构体(MATLAB struct在Python中会被转为dict) for key, value in obj.items(): new_prefix = f"{prefix}_{key}" if prefix else key flat_dict.update(flatten_struct(value, new_prefix)) elif isinstance(obj, list): # 处理MATLAB的cell数组(转为逗号分隔字符串) flat_dict[prefix] = ','.join(map(str, obj)) else: # 基础数据类型直接保留 flat_dict[prefix] = obj return flat_dict # 加载MAT文件,squeeze_me压缩单维度数组,struct_as_record保留结构体格式 mat_data = sio.loadmat('def.mat', struct_as_record=False, squeeze_me=True) data_array = mat_data['data'] # 扁平化所有结构体元素 flat_records = [flatten_struct(item) for item in data_array] # 转为DataFrame并导出CSV df = pd.DataFrame(flat_records) df.to_csv('output.csv', index=False, encoding='utf-8')
注意:如果你的嵌套结构包含更复杂的类型(比如cell内嵌套结构体),可以扩展flatten_struct函数的分支逻辑来适配。
内容的提问来源于stack exchange,提问作者Kiana Kazeminejad
相关产品推荐
相关产品推荐

