动机
部分项目的测试代码使用的还是matlab, 但是由于excel处理数据的便利, 以及对于手工输入数据的厌恶, 我研究了下如何将计算得到的保存在mat文件中的数据导出到xls或者xlsx文件里.
环境
方法
首先不得不说, matlab的帮助文档真的是很详细, 很全面, 尤其是最近的几个版本, 中文文档也愈发的齐全起来, 没事多查文档还是很有用的.
首先分析下我们的数据, 从我实际使用来看, 其实主要有字符串, 数字这两种类型的数据., 为了方便整合, 以及一次性写入, 我们可以使用matlab的元胞数组来构造整体表格数据.
元胞数组是一种包含名为元胞的索引数据容器的数据类型,其中的每个元胞都可以包含任意类型的数据。元胞数组通常包含不同长度的字符向量列表,或字符串和数字的混合,或不同大小的数值数组。 通过将索引括在圆括号
**()**
中可以引用元胞集。使用花括号**{}**
进行索引来访问元胞的内容。
通过逐行构造数据, 我们最终可以得到一个包含了所有想要的数据的元胞数组, 这里有模型名字, 有模型结果, 也有不同指标的名字. 我们需要做的就是将这个数组写入xls或者xlsx文件中.
我们可以到文档中搜索与 excel
相关的内容.
这里推荐我们使用 writetable
函数.
为了了解该函数的用法, 我们直接看他的文档 (这里贴的是R2019a的文档, 因为可以直接在浏览器里收到, 基本内容没变)可以了解到, 他是把一个表数据写入到文件中.
writetable
根据指定扩展名确定文件格式。扩展名必须是下列格式之一:
.txt
、.dat
或.csv
(适用于带分隔符的文本文件).xls
、.xlsm
或.xlsx
(适用于 Excel® 电子表格文件).xlsb
(适用于安装了 Windows® Excel 的系统上支持的 Excel 电子表格文件)
而我们现在的数据是元胞数组, 并不能直接写入, 会提示你如下错误:
Undefined function 'write' for input arguments of type 'cell'.
Error in writetable (line 124)
write(a,filename,varargin{:})
所以我们需要将元胞数组转化为表数据. 在页面https://ww2.mathworks.cn/help/matlab/tables.html中可以看到, 这里展示了关于表数据的各种操作, 其中就有使用元胞数组创建表数据, 也就是使用函数 [cell2table](https://ww2.mathworks.cn/help/matlab/ref/cell2table.html)
.
可以了解到, 表数据是以列为基准的, 所以对于每一列, 会指定对应的名字. 如果不指定, 会按照默认的格式创建. 我们因为数据的第一行实际上就可以认为是列数据的名字, 所以可以参考给出的示例里的 将列标题转换为变量名称
这一小节的代码.
将元胞数组转换为表,然后包括元胞数组的第一行作为表的变量名称。 创建一个元胞数组,其中第一行包含用于标识列标题的字符向量。
示例代码如下:
Patients = {'Gender' 'Age' 'Height' 'Weight' 'Smoker';...
'M' 38 71 176 true;...
'M' 43 69 163 false;...
'M' 38 64 131 false;...
'F' 38 64 131 false;...
'F' 40 67 133 false;...
'F' 49 64 119 false}
C = Patients(2:end,:);
T = cell2table(C)
T.Properties.VariableNames = Patients(1,:)
即先按照正常的方式转换数据, 这里把第一行排除掉了, 最后通过修改表的属性来讲第一行替换为原始的数据.由此, 我们可以得到真正可以写入表格的数据了.
代码
data_name = 'DUT-OMRON';
output_folder = './Results/';
mat_path = [output_folder, data_name, '/'];
fprintf("Dataset Name: %s\n", data_name);
fprintf("Output Folder Name: %s\n", output_folder);
fprintf("Mat File Path: %s\n", mat_path);
if(isfolder(mat_path) && ~isempty(mat_path))
mat_list = dir(mat_path);
mat_list = mat_list(3:end, 1);
else
fprintf("%s should be a folder that has some files\n", mat_path);
end
num_model = length(mat_list);
output_data = cell(num_model + 1, 7);
output_data(1, :) = {'Model', 'MaxF', 'MeanF', 'WFm', 'Emeasure', 'Smeasure', 'MAE'};
for i = 1 : num_model
mat_data = load([mat_path, mat_list(i).name]);
model_name = strsplit(mat_list(i).name, '.');
output_data(i + 1, :) = { ...
model_name{1}, ...
mat_data.MaxFmeasure, ...
mat_data.mean_Fmeasure(3), ...
mat_data.wFmeasure, ...
mat_data.Emeasure, ...
mat_data.S_measure, ...
mat_data.MAE
};
end
output_data_model = output_data(2:end, :);
output_table = cell2table(output_data_model);
output_table.Properties.VariableNames = output_data(1, :);
filename = [output_folder, 'record.xls'];
% 这里针对不同的sheet使用对应的data_name作为名字
writetable(output_table, filename, 'Sheet', data_name, 'Range', 'A1')