【问题标题】:Exporting data from Matlab (.mat file) into an existing Excel sheet at a specific range将数据从 Matlab(.mat 文件)导出到特定范围内的现有 Excel 工作表中
【发布时间】:2021-03-16 07:31:14
【问题描述】:

以下 Matlab 脚本创建一个 .mat 文件。其中有多个案例。每个案例都有不同的输出。我多次运行此脚本并将输出手动存储在 Excel 表like this 中。例如,在第一次运行脚本后,我将输出保存在 Run1 列下,第二次保存在 Run2 中。从 Run 3 开始,我想让 matlab 从 .mat 文件中导出结果,而无需手动输入。

注意:唯一改变的值是每次运行的输出值。每次跑步的休息时间都是一样的。

%% Example of how the data is structured

% initialize testSetup
testSetup = struct( ...
    'name', {'01_Case1', '01_Case2', '01_Case3' , ...
              '02_Case1', '02_Case2','02_Case3','02_Case4' ...
              '03_Case1','03_Case2','03_Case3',...
              '04_Case1','04_Case2'}, ...
     'rollno',  {struct, struct, struct,struct, struct, struct,struct,...
                struct, struct,struct, struct, struct},...
     'subject', {struct, struct, struct,struct, struct, struct,struct,...
                struct, struct,struct, struct, struct},...
    'evaluation',{struct, struct, struct,struct, struct, struct,struct,...
                struct, struct,struct, struct, struct});
%input the data
testSetup(1).evaluation.output1.result=0.1; 
testSetup(1).evaluation.output2.result=0.2;
testSetup(1).evaluation.output3.result=0.3;
testSetup(2).evaluation.output1.result=0.1;
testSetup(2).evaluation.output2.result=0.2;
testSetup(2).evaluation.output3.result=0.3;
testSetup(2).evaluation.output4.result=0.4;
testSetup(3).evaluation.output1.result=0.1;
testSetup(3).evaluation.output2.result=0.2;
testSetup(3).evaluation.output3.result=0.3;
testSetup(4).evaluation.output1.result=0.1;
testSetup(4).evaluation.output2.result=0.2;
testSetup(5).evaluation.output1.result=0.1; 
testSetup(5).evaluation.output2.result=0.2;
testSetup(5).evaluation.output3.result=0.3;
testSetup(6).evaluation.output1.result=0.1;
testSetup(6).evaluation.output2.result=0.2;
testSetup(6).evaluation.output3.result=0.3;
testSetup(7).evaluation.output1.result=0.1;
testSetup(7).evaluation.output2.result=0.2;
testSetup(7).evaluation.output3.result=0.3;
testSetup(8).evaluation.output1.result=0.1;
testSetup(8).evaluation.output2.result=0.2;
testSetup(9).evaluation.output1.result=0.1;
testSetup(9).evaluation.output2.result=0.2;
testSetup(9).evaluation.output3.result=0.3;
testSetup(10).evaluation.output1.result=0.1;
testSetup(10).evaluation.output2.result=0.2;
testSetup(11).evaluation.output1.result=0.1;
testSetup(11).evaluation.output2.result=0.2;
testSetup(11).evaluation.output3.result=0.3;
testSetup(12).evaluation.output1.result=0.1;
testSetup(12).evaluation.output2.result=0.2;
%save as .mat
save testsetup.mat

【问题讨论】:

  • 请添加您的 Matlab 脚本

标签: excel matlab


【解决方案1】:

这里有两种方法可以做到这一点。

首先,让我们定义数据。您的问题不是 100% 清楚您的数据的结构,因此您必须将其转换为这种格式。

header = {'Exp1', 'Exp2', 'Exp3'};

case1 = { ...
    'class1', 90, 91;
    'class2', 91, 91;
    'class3', 92, 91;
    'class4', 93, 91;
    };
case2 = { ...
    'class1', 90, 92;
    'class2', 91, 92;
    'class3', 92, 92;
    };
case3 = { ...
    'class1', 90, 93;
    'class2', 91, 93;
    'class3', 92, 93;
    };
case4 = { ...
    'class1', 90, 90;
    'class2', 91, 90;
    'class3', 92, 90;
    };

第一种方法将每个组件分别写入到工作表Sheet1

xlswrite('temp.xlsx', header, 'Sheet1', 'B1');
xlswrite('temp.xlsx', {'Case1'}, 'Sheet1', 'A2');
xlswrite('temp.xlsx', case1, 'Sheet1', 'A3');
xlswrite('temp.xlsx', {'Case2'}, 'Sheet1', 'A8');
xlswrite('temp.xlsx', case2, 'Sheet1', 'A9');
xlswrite('temp.xlsx', {'Case3'}, 'Sheet1', 'A13');
xlswrite('temp.xlsx', case3, 'Sheet1', 'A14');
xlswrite('temp.xlsx', {'Case4'}, 'Sheet1', 'A18');
xlswrite('temp.xlsx', case4, 'Sheet1', 'A19');

第二种方法在一次写入操作中将整个内容写入表Sheet2,产生等效输出:

blank_row = repmat({NaN}, 1, 4);
C = cat(1, ...
    cat(2, {NaN}, header), ...
    {'Case1', NaN, NaN, NaN}, ...
    cat(2, case1, repmat({NaN}, size(case1, 1), 1)), ...
    blank_row, ...
    {'Case2', NaN, NaN, NaN}, ...
    cat(2, case2, repmat({NaN}, size(case2, 1), 1)), ...
    blank_row, ...
    {'Case3', NaN, NaN, NaN}, ...
    cat(2, case3, repmat({NaN}, size(case3, 1), 1)), ...
    blank_row, ...
    {'Case4', NaN, NaN, NaN}, ...
    cat(2, case4, repmat({NaN}, size(case4, 1), 1)));
xlswrite('temp.xlsx', C, 'Sheet2');

【讨论】:

  • 不幸的是,我无法在此处添加 Matlab 脚本,如果我有 20 个输出怎么办。我是否必须编写您为 20 个输出编写的代码?还是有其他方法?谢谢。
  • 您能否分享重现您的结构体数组的 MATLAB 代码?当然有一种方法可以自动生成要写入 Excel 的元胞数组(例如通过在结构数组上调用 fieldnames 并进行迭代)。
  • 我找不到在此处添加它的方法,原因有两个。 1.脚本使用多个函数文件来获得最终结果 2.我不能透露。话虽如此,我将尝试访问正在存储的 .mat 文件的输出,并将它们逐个添加到特定的行和列。但我相信会有点长。
  • 嗯,你能用 struct 命令和赋值重现类似的东西吗?例如,s = struct; s.Case1.class1 = 90; s.Case1.class2 = 91; s.Case2.class1 = 90; - 这是否给出了相同格式的内容?
  • 是的,几乎相似。有一些更改,所以我创建了一个 testSetup.mat 文件并在上面附上了 3 张图片。请跟随他们以获得这个想法。看到它们后,如图 3 所示,输出值为 0.2550。这就是我需要将 Excel 表导出到特定行和列的内容。 (另外,大约有 20 个 Case,例如 Case1,Cas2...Case20。testSetup 的大小为 1*26)。
【解决方案2】:

根据您提供的图片,您的数据的结构类似于以下内容(示例数据基于您的图片)。这当然不必手动编码 - testSetup 的实例将来自您的脚本,您只需将它们附加到 experiment

如果您的数据结构不同,您可能需要稍微调整下面的代码。但是,更改不应太显着。

%% Create sample data

% initialize testSetup
testSetup = struct( ...
    'name', {'Case1', 'Case2', 'Case3'}, ...
    'A', {struct, struct, struct}, ...
    'B', {struct, struct, struct}, ...
    'C', {struct, struct, struct});

% assume there are two experiments
experiment = struct('testSetup', {testSetup, testSetup});

% sample data for experiment 1
experiment(1).testSetup(1).C.class1.output = 90;
experiment(1).testSetup(1).C.class2.output = 91;
experiment(1).testSetup(1).C.class3.output = 92;
experiment(1).testSetup(1).C.class4.output = 93;
experiment(1).testSetup(2).C.class1.output = 90;
experiment(1).testSetup(2).C.class2.output = 91;
experiment(1).testSetup(2).C.class3.output = 92;
experiment(1).testSetup(3).C.class1.output = 90;
experiment(1).testSetup(3).C.class2.output = 91;
experiment(1).testSetup(3).C.class3.output = 92;
experiment(1).testSetup(4).C.class1.output = 90;
experiment(1).testSetup(4).C.class2.output = 91;
experiment(1).testSetup(4).C.class3.output = 92;

% sample data for experiment 2
experiment(2).testSetup(1).C.class1.output = 91;
experiment(2).testSetup(1).C.class2.output = 91;
experiment(2).testSetup(1).C.class3.output = 91;
experiment(2).testSetup(1).C.class4.output = 91;
experiment(2).testSetup(2).C.class1.output = 92;
experiment(2).testSetup(2).C.class2.output = 92;
experiment(2).testSetup(2).C.class3.output = 92;
experiment(2).testSetup(3).C.class1.output = 93;
experiment(2).testSetup(3).C.class2.output = 93;
experiment(2).testSetup(3).C.class3.output = 93;
experiment(2).testSetup(4).C.class1.output = 90;
experiment(2).testSetup(4).C.class2.output = 90;
experiment(2).testSetup(4).C.class3.output = 90;

现在我们有了数据,我们可以将其写入 Excel。我们的计划是将其写入元胞数组,一次一个实验。

此代码假定每个实验的 testSetup 结构相似。特别是,它假设每个实验的案例名称相同,并且每个案例中的类别相同。这两个假设已在代码中明确检查。

%% Output to Excel

% CREATE CELL TO WRITE TO FILE (cell_to_write)

% initialize to overall header row
cell_to_write = cat(2, {NaN}, ...
    cellfun(@(x)sprintf('Exp%d', x), num2cell(1 : length(experiment)), 'UniformOutput', false));

% names of cases
case_names = experiment(1).testSetup(casenum).name;
% ... check that each experiment has the same cases
for expnum = 1 : length(experiment)
    if ~isequal(case_names, experiment(expnum).testSetup(casenum).name)
        error('Cases are different for different experiments');
    end
end

% create remainder of cell
for casenum = 1 : length(experiment(1).testSetup) % iterate over cases

    % header row for current case
    curr_header = cat(2, ...
        {case_names}, ...
        repmat({NaN}, 1, length(experiment)));

    % classes within current case
    curr_classes = fieldnames(experiment(1).testSetup(casenum).C);

    % body for current case
    % ... write names of classes
    curr_body = cat(2, ...
        curr_classes, ...
        repmat({NaN}, length(curr_classes), length(experiment)));
    % ... write numeric data
    for expnum = 1 : length(experiment) % iterate over experiments
        % check that each experiment has the same classes for the current case
        if ~isequal(curr_classes, fieldnames(experiment(expnum).testSetup(casenum).C))
            error('Classes are different for different experiments');
        end
        for classnum = 1 : length(curr_classes)
            curr_body{classnum, expnum + 1} = ...
                experiment(expnum).testSetup(casenum).C.(curr_classes{classnum}).output;
        end
    end

    % append current case to cell
    cell_to_write = cat(1, ...
        cell_to_write, ...
        curr_header, ...                            % current header
        curr_body, ...                              % current body
        repmat({NaN}, 1, size(cell_to_write, 2)));  % blank row
end

% WRITE TO FILE

xlswrite('temp.xlsx', cell_to_write, 'Sheet1');

【讨论】:

  • 嗨,我正在研究这个与主要项目并行的项目。 (我必须将其集成到主项目中)。我一定会在这里发布我的更新。抱歉,需要很长时间,非常感谢。
  • 太棒了!我这边当然不急,只要确保你有你需要的帮助!
  • 嗨,我开始解决这个问题,我有几个问题。 1. 您提到将 testsetup 中的数据附加到实验中,但我认为这似乎是一个漫长的过程(我可能错了),因为我有超过 26 个案例。 2.在脚本“输出到excel”中,“casenum”是什么。如果不能清楚地表达我的问题,我很抱歉。我是否应该创建另一个线程来解释问题(其中包括创建 .mat 文件的代码)?非常感谢。
  • (1) 与此答案中的代码类似的东西应该适用于任何数量的情况——它是 3 还是 26 都没有关系。(2) casenum 是一个用于迭代的变量在这些情况下 - 它是在for casenum = 1 : length(experiment(1).testSetup) % iterate over cases 行上计算的(请参阅for 的 MATLAB 文档:mathworks.com/help/matlab/ref/for.html)。 (3) 您可以编辑原始问题以包含创建 .mat 文件的代码 - 这比创建新问题要好得多,以保持 StackOverflow 干净。
  • 我已经编辑了这个问题。如果它看起来完全像一个不同的问题,我很抱歉。这是我第一次在网上问的问题。所以很难解释。感谢理解。
【解决方案3】:

所以,我解决它的方法是找到我的数据集(.mat 文件)的大小并迭代案例数量,并访问每个案例的输出,然后将其转换为数组,以便它可以轻松复制到 Excel 工作表中。

注意:如果有case值为空的场景,那么可以使用for循环来检查空值并用NaN替换。

sz = size(testsetup,2);
exportArr=[];

% Converting to an array and transposing it to make it a column and later on copying 
% it into an Excel Sheet.

for i = 1:sz
    str = struct2array(testSetup(i).evaluation); 
    data = struct2array(str);
    exportArr = [exportArr;nan;data'];
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多