Arrays 对包含奇数数组的结构中的每个元素求和[MATLAB]

Arrays 对包含奇数数组的结构中的每个元素求和[MATLAB],arrays,matlab,data-structures,cells,Arrays,Matlab,Data Structures,Cells,我花了一些时间研究这一点,但我可能错过了一些简单的东西。我有中级的Matlab知识 我有一个从实验中保存的数据结构 1x30 struct array with fields: pixelStats: [118.6892 3.1370e+003 -0.1418 2.1195 -25.9308 259.3778] pixelLPStats: [5x2 double] autoCorrReal: [9x9x5 double] autoCorrMag: [4-D double]

我花了一些时间研究这一点,但我可能错过了一些简单的东西。我有中级的Matlab知识

我有一个从实验中保存的数据结构

1x30 struct array with fields:
pixelStats: [118.6892 3.1370e+003 -0.1418 2.1195 -25.9308 259.3778]
  pixelLPStats: [5x2 double]
  autoCorrReal: [9x9x5 double]
   autoCorrMag: [4-D double]
      magMeans: [18x1 double]
 cousinMagCorr: [4x4x5 double]
 parentMagCorr: [4x4x4 double]
cousinRealCorr: [8x8x5 double]
parentRealCorr: [8x8x4 double]
   varianceHPR: 21.5116
其中每个子字段(“数组”?很抱歉,术语可能不正确)的大小不同。我需要对30个条目(试验)进行平均,以便保留上面的形状,但每个字段中每个单元格的值在30个试验中进行平均。我还需要方差(我试图计算Z分数,看看其他试验是否与该人群有显著差异)

首先我尝试在for循环中这样做,在那里我得到字段名,然后对于每个字段,我打断并尝试在30次试验中为每个元素添加值,尽管这种策略不适用于具有不同大小维度的字段(例如,我需要根据当前字段的维度为循环创建不同大小的值)

然后,我尝试将数据结构转换为一个单元格数组,这是可行的

cell_in = struct2cell(s_params_in)

cell_in = 10x1x30  607440  cell 
…然后我尝试了一些我在搜索中发现的使用cellfun的东西,不过说实话,我并不完全确定它是如何工作的。我必须添加UniformOutput来处理大小不等的字段

cellfun( @(cell_in) sum(cell_in(:)), cell_in,'UniformOutput',false)
这将对所有30次试验中每个“字段”(第一维度)内的所有值进行汇总,并在其中的元素之间折叠。e、 g

ans(:,:,30) = 

[3.4911e+003]
[    10.9414]
[2.0854e+009]
[2.6877e+007]
[1.3612e+004]
[2.3328e+006]
[8.4917e+004]
[7.3826e+008]
[8.2038e+003]
[    22.4030]
我试着玩弄如何在(:)部分中调用cell_,但无法得到我想要的结果,即在保留其他维度的同时,在维度上求和一个数组以进行试验

我还尝试将其转换为矩阵,然后我可以使用

sum([data(:)])
重新调整形状以恢复原始尺寸,尽管这似乎也很困难,我可能必须按字段进行,并手动输入尺寸。由于尺寸不一致,cell2mat无论如何都不起作用

所以现在我的知识已经到了极限,正在寻求帮助,有人能解决这个问题吗

干杯, Alex

一个工作代码

clear;clc

% create an example struct array
field1 = 'f1';  value1 = rand(1,10);
field2 = 'f2';  value2 = {rand(3,4,2), rand(3,4,2)};
field3 = 'f3';  value3 = {pi, pi.^2};
field4 = 'f4';  value4 = {magic(3), magic(3).^2};
S = struct(field1,value1,field2,value2,field3,value3,field4,value4);
clearvars field* value*

N = length(S);
T = struct();
U = T;

% enumerate over all fields (all should be numbers)
FN = fieldnames(S);
for ii=1:length(FN)
    fn = FN{ii};
    ss = {S.(fn)};
%     convert cell array of N-dim matrices into one (N+1)-dim matrix
    ssdim = ndims(ss{1});
    TT = cell2mat( reshape(ss, [ones(1,ssdim),N]) );
%     here you can do what you want
    T.(fn) = mean(TT,ndims(TT));
    U.(fn) = var(TT,0,ndims(TT));
end
clearvars ii ssdim ss fn TT

for ii=1:length(FN)
    disp(FN{ii})
    disp(T.(FN{ii}))
    disp(U.(FN{ii}))
end
clearvars ii N
代码注释中介绍了基本步骤
TT
是一种特定类型实验数据的30次试验。假设您正在迭代字段
pixelLPStats
。每个试验都有一个由该名称分配的矩阵,它是一个5x2双数组。因此,
TT
将是一个5x2x30阵列。你可以用它做你想做的事。然后让循环将您带到下一个字段


我想这次我得到了正确的答案

>> ( S(1).f2 + S(2).f2 )/2 == T.f2

ans(:,:,1) =

     1     1     1     1
     1     1     1     1
     1     1     1     1


ans(:,:,2) =

     1     1     1     1
     1     1     1     1
     1     1     1     1

>> 

将N维矩阵单元数组转换为一(N+1)维矩阵的另一种方法-

@Yvon

谢谢你的回复,代码看起来很棒,我已经花了时间来阅读了。我会把这个存档,因为它有一些我不知道的快捷方式。不幸的是,这似乎并没有解决我的问题,可能是因为我缺乏经验,也无法利用你的慷慨捐助为我工作。撇开卑躬屈膝不谈,我的结果如下

pixelStats: [1x6x30 double]
  pixelLPStats: [1x2x30 double]
  autoCorrReal: [1x9x150 double]
   autoCorrMag: [4-D double]
      magMeans: [1x1x30 double]
 cousinMagCorr: [1x4x150 double]
 parentMagCorr: [1x4x120 double]
cousinRealCorr: [1x8x150 double]
parentRealCorr: [1x8x120 double]
   varianceHPR: [1x1x30 double]
首先,当我一步一步地运行代码时,均值/方差部分似乎不起作用,它只是用MX30数组而不是每个元素均值的mxnx1数组填充该字段。同样值得关注的是上述输出的尺寸。请注意,表示30次试验的尺寸标注已添加到每个字段中,其中一些似乎已将30乘以最后一个尺寸标注。例如,复制这些字段,顶部为原始字段,底部为您的输出:

cousinMagCorr: [4x4x5 double]
vs

请注意,最终尺寸乘以30?我在尝试循环字段并将单元格转换为矩阵时遇到了这个问题;它们适用于2d,但不适用于更高的配置,就像您的输出一样,最后一个维度乘以n次试验

很可能我不清楚;我希望得到类似于结构中第一个条目的东西,其中每个字段中的所有值对应于所有30次试验中该值的平均值。我对每个单独的值都感兴趣,而不是在字段中跨维度折叠

再次感谢,
Alex

Edit*努力适应我的回复,我将发布一个回复到我的原始版本如果它仍然不起作用,你能给我一个
autocorreal
的例子吗?我做了一个快速修复。我在转换单元格数组时出错了。尝试新代码:)惊人!你真的超越了我,我非常感激。这个问题在周末困扰了我,对我的实验至关重要,而且对时间非常敏感,因此我没有学习,而是主动接触。非常感谢您的投入。
cousinMagCorr: [1x4x150 double]