计算结构单元格中同名字段的平均值
Calculate means of fields with same name in cell of structures
我有一个包含多个结构的单元格,其中包含来自 MirToolBox mirfeatures() 函数的多个音频信号的输出。每个结构的字段名称都相同。
所以数据看起来像这样,但更大。 c{1} 是第一个结构,c{2} 是第二个结构等。两个结构包含相同的字段名称。
c{1}.field1.field1A=1;
c{1}.field1.field1B=2;
c{1}.field1.field1C=3;
c{1}.field2.field2D.field2E=4;
c{1}.field2.field2D.field2F=5;
c{1}.field3=6;
c{1}.field4.field4A.field4B.field4C=7;
c{1}.field4.field4A.field4B.field4D=8;
c{2}.field1.field1A=9;
c{2}.field1.field1B=10;
c{2}.field1.field1C=11;
c{2}.field2.field2D.field2E=12;
c{2}.field2.field2D.field2F=13;
c{2}.field3=14;
c{2}.field4.field4A.field4B.field4C=15;
c{2}.field4.field4A.field4B.field4D=16;
我想跨结构计算每个字段的平均值,例如
c{1}.field1.field1A, c{2}.field1.field1A,.. c{n}.field1.field1A=9
的平均值。
考虑到我正在使用的实际结构每个都接近一百个字段,是否有一种直接的方法可以做到这一点?
谢谢
您可以使用 cell2mat
将元胞数组转换为结构数组,然后访问整个 整个 数组的字段(而不是简单地从单个该数组中的结构元素)以获取 comma-separated 列表。如果该字段指向另一个结构,您的逗号分隔列表将是一个逗号分隔的结构列表!
然后您可以再次将 comma-separated 列表收集到元胞数组中,方法是用 {}
包围它,然后再次执行 cell2mat
,等等struct,以获得与初始元胞数组大小相同的结构数组,仅包含您需要的字段。
当您最终向下移动足够多的级别到达感兴趣的领域时,您可以将其再次收集为逗号分隔列表,并将其环绕 []
使其成为一个矩阵,您可以可以用作函数的参数(例如 mean)。
不幸的是,您必须为您拥有的每个唯一的最内层字段执行此操作,因为它们之间没有一致性。但它确实允许您在单个操作中为每个唯一字段处理所有 N 个单元格。
例如给定上面大小为 2 的单元格,如果我们将 s0、s1、s2 表示为最外层、一层深、两层深等,则:
% Convert outer cell array to struct array representing outermost level
s0 = cell2mat(c); % -> 1x2 struct array containing the fields: field1, field2, field3, field4
% field 1 - subfields of interest are 1 level deep
s1 = cell2mat({s0.field1}); % -> 1x2 struct array containing the fields: field1A, field1B, field1C
field1A_mean = mean([s1.field1A])
field1B_mean = mean([s1.field1B])
field1C_mean = mean([s1.field1C])
% field 2 - subfields of interest are 2 levels deep
s1 = cell2mat({s0.field2}); % -> 1x2 struct array containing the field: field2D
s2 = cell2mat({s1.field2D}); % -> 1x2 struct array containing the fields: field2E, field2F
field2E_mean = mean([s2.field2E])
field2F_mean = mean([s2.field2F])
% field 3 - collect at this level
field3_mean = mean([s0.field3])
% field 4 subfields of interest are 3 levels deep
s1 = cell2mat({s0.field4});
s2 = cell2mat({s1.field4A});
s3 = cell2mat({s2.field4B});
field4C_mean = mean([s3.field4C])
field4D_mean = mean([s3.field4D])
我有一个包含多个结构的单元格,其中包含来自 MirToolBox mirfeatures() 函数的多个音频信号的输出。每个结构的字段名称都相同。
所以数据看起来像这样,但更大。 c{1} 是第一个结构,c{2} 是第二个结构等。两个结构包含相同的字段名称。
c{1}.field1.field1A=1;
c{1}.field1.field1B=2;
c{1}.field1.field1C=3;
c{1}.field2.field2D.field2E=4;
c{1}.field2.field2D.field2F=5;
c{1}.field3=6;
c{1}.field4.field4A.field4B.field4C=7;
c{1}.field4.field4A.field4B.field4D=8;
c{2}.field1.field1A=9;
c{2}.field1.field1B=10;
c{2}.field1.field1C=11;
c{2}.field2.field2D.field2E=12;
c{2}.field2.field2D.field2F=13;
c{2}.field3=14;
c{2}.field4.field4A.field4B.field4C=15;
c{2}.field4.field4A.field4B.field4D=16;
我想跨结构计算每个字段的平均值,例如
c{1}.field1.field1A, c{2}.field1.field1A,.. c{n}.field1.field1A=9
的平均值。
考虑到我正在使用的实际结构每个都接近一百个字段,是否有一种直接的方法可以做到这一点?
谢谢
您可以使用 cell2mat
将元胞数组转换为结构数组,然后访问整个 整个 数组的字段(而不是简单地从单个该数组中的结构元素)以获取 comma-separated 列表。如果该字段指向另一个结构,您的逗号分隔列表将是一个逗号分隔的结构列表!
然后您可以再次将 comma-separated 列表收集到元胞数组中,方法是用 {}
包围它,然后再次执行 cell2mat
,等等struct,以获得与初始元胞数组大小相同的结构数组,仅包含您需要的字段。
当您最终向下移动足够多的级别到达感兴趣的领域时,您可以将其再次收集为逗号分隔列表,并将其环绕 []
使其成为一个矩阵,您可以可以用作函数的参数(例如 mean)。
不幸的是,您必须为您拥有的每个唯一的最内层字段执行此操作,因为它们之间没有一致性。但它确实允许您在单个操作中为每个唯一字段处理所有 N 个单元格。
例如给定上面大小为 2 的单元格,如果我们将 s0、s1、s2 表示为最外层、一层深、两层深等,则:
% Convert outer cell array to struct array representing outermost level
s0 = cell2mat(c); % -> 1x2 struct array containing the fields: field1, field2, field3, field4
% field 1 - subfields of interest are 1 level deep
s1 = cell2mat({s0.field1}); % -> 1x2 struct array containing the fields: field1A, field1B, field1C
field1A_mean = mean([s1.field1A])
field1B_mean = mean([s1.field1B])
field1C_mean = mean([s1.field1C])
% field 2 - subfields of interest are 2 levels deep
s1 = cell2mat({s0.field2}); % -> 1x2 struct array containing the field: field2D
s2 = cell2mat({s1.field2D}); % -> 1x2 struct array containing the fields: field2E, field2F
field2E_mean = mean([s2.field2E])
field2F_mean = mean([s2.field2F])
% field 3 - collect at this level
field3_mean = mean([s0.field3])
% field 4 subfields of interest are 3 levels deep
s1 = cell2mat({s0.field4});
s2 = cell2mat({s1.field4A});
s3 = cell2mat({s2.field4B});
field4C_mean = mean([s3.field4C])
field4D_mean = mean([s3.field4D])