是否有可能在没有循环的情况下在Matlab中对多个结构子字段进行平均?

时间:2018-01-08 06:15:37

标签: arrays matlab struct

我有一个处理单个数据集的函数,并将结果指标存储在数据集中,如下所示:

trial_data.output_metric_a.value_1 = 2;
...
trial_1 = trial_data;

此函数适用于许多不同的试验,并存储为数组结构:

% trial_1.output_metric_a.value_1 = 4
% trial_2.output_metric_a.value_1 = 2
trials = [trial_1 ; trial_2];

是否可以获得子字段值的平均值和标准差 没有循环数据结构?

理想情况下:

mean_trials = mean(trials)
mean_trials.output_metric_a.value_1 == 3 % true

可能的循环实现可以解决这个问题(显然这有很多不足之处):

output_metric_a_value_1 = [];
...

for i:length(trials)
    output_metric_a_value_1(end+1) = trials(i).output_metric_a.value_1; 
    ... % For each output metric and value
end

mean_trials.output_metric_a.value_1 = mean(output_metric_a_value_1);

3 个答案:

答案 0 :(得分:4)

您可以将主结构转换为单元格,然后对内容进行操作:

% your data base:
trial_1.output_metric_a.value_1 = 4
trial_2.output_metric_a.value_1 = 2
trials = [trial_1 ; trial_2];

% convert to cell:
Ctrials=struct2cell(trials);
Atrials=[Ctrials{:}];
meanTrials=mean([Atrials.value_1])
meanTrials=
     3

答案 1 :(得分:2)

特殊解决方案(非嵌套struct>数组)

正如已经提到的,只针对一个级别的结构字段(不是嵌套的),基本上可以用于单行:

sarr_mean = cellfun(@(fn) mean([sarr.(fn)]), fieldnames(sarr))

备注:在非嵌套的情况下,实际上不需要将结果数组分配回结构。如果需要,您可以类似于下面的完整解决方案。

完整解决方案(嵌套结构>嵌套结构)

但是,对于任意嵌套的数组,我建议使用如下函数:

% f... function handle
% s... nested struct array
function sarr_res = nestedSarrFun(f, s)
    if isstruct(s)
        % get fieldnames:
        fns = fieldnames(s);
        % get content:
        con = cellfun(@(fn) nestedSarrFun(f, [s.(fn)]), ...
                      fns, 'UniformOutput', false);
        % create return struct
        fnsCon = reshape([fns(:), con(:)]', [1,2*numel(fns)]);
        sarr_res = struct(fnsCon{:});
    else
        sarr_res = f(s);
    end
end

使用示例

定义示例结构数组并通过mean应用nestedSarrFun

% define example struct array "sarr" with fields
%   .foo.bar1
%       .bar2
%   .dings
sarr = struct();
sarr(1).foo.bar1 = 2;
sarr(1).foo.bar2 = 7;
sarr(1).dings   = 1;
sarr(2).foo.bar1 = 5;
sarr(2).foo.bar2 = 5;
sarr(2).dings   = 2;

% apply mean to all nested fields:
sarr_mean = nestedSarrFun(@mean, sarr);

示例结果:

sarr_mean.foo.bar1 = 3.5
sarr_mean.foo.bar2 = 6
sarr_mean.dings = 1.5

答案 2 :(得分:1)

在Matlab2017中(我不确定旧版本),一个结构数组可以返回其结构字段的数组,如下所示:

struct1.x = 1;
struct2.x = 2;

% array of 2 structs:
struct_array = [struct1, struct2];

% array of field x of each struct:
[struct_array.x]

返回

ans =

     1     2

在您的情况下,数据不在结构的字段中,而是在子字段output_metric_a中。因此,您首先需要两次:

trial1.output_metric_a.value_1 = 1;
trial2.output_metric_a.value_1 = 2;

trials = [trial1, trial2];

output_metric_a_array = [trials.output_metric_a];

value_1_array = [output_metric_a_array.value_1];

mean_of_value_1 = mean(value_1_array)

返回

mean_of_value_1 =

    1.5000