我花了一些时间研究这个,但可能会遗漏一些简单的事情。我有中级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个试验,(第一维),在其中的元素之间折叠。例如
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_in(:)部分,但无法获得我正在寻找的结果,即在整个维度上求解的数组,同时保留其他维度。
我还尝试将其转换为矩阵,然后我可以使用类似
的东西sum([data(:)])
然后重新整形以恢复原始尺寸,虽然这似乎也很困难,我可能不得不每个字段都这样做并手动输入尺寸。由于尺寸不一致,cell2mat无论如何都无法工作。
所以,现在我的知识极限并且正在寻求帮助,任何人都可以解决这个问题吗?
干杯, 亚历
答案 0 :(得分:1)
工作代码。
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)维度矩阵的另一种方法 - How to average over a cell-array of arrays?
答案 1 :(得分:0)
@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]
首先,当我逐步执行代码时,均值/方差部分似乎不起作用,它只是使用mxmx30数组填充该字段,而不是每个元素的mxnx1数组'是的意思。还有关于上述输出的尺寸。请注意,表示30个试验的维度已添加到每个字段中,有些似乎与最后一个维度相乘30。例如,comapre这些字段,顶部是原始字段,底部是输出:
cousinMagCorr: [4x4x5 double]
VS。
cousinMagCorr: [1x4x150 double]
注意最终尺寸乘以30?我遇到了这个问题,试图遍历字段并将单元格转换为矩阵;他们工作了2d,但没有更高的配置,就像你的输出一样,最后一个维度乘以n次试验。
很可能我不清楚;我希望得到类似结构中的第一个条目,其中每个字段中的所有值对应于30个试验中该值的平均值。我对每个单独的值感兴趣,而不是在字段中跨维度折叠。再次感谢, 亚历