在Matlab中计算一个三维cell数组的均值。

3
我有一个大小为<20x1x19>的单元数组C,其中每个19个元素都包含20个大小为(80x90)的矩阵集合,
我想计算每个20个矩阵的平均值,并将结果存储在一个矩阵M中,以便最终我将拥有一个大小为80x90x19的矩阵,其中包含单元数组矩阵的平均值。
例如:
M(:,:,1) 将拥有 C(:,:,1) 中元素的平均值;
M(:,:,2) 将拥有 C(:,:,2) 中元素的平均值
等等。
2个回答

4
稍微进行一些数组操作,就能避免使用循环。你可以改变细胞数组的维度,以便cell2mat的结果得到一个80x90x19x20的数组,之后你只需要沿着第4个维度取平均值即可:
%# C is a 20x1x19 cell array containing 80x90 numeric arrays

%# turn C into 1x1x19x20, swapping the first and fourth dimension
C = permute(C,[4 2 3 1]);

%# turn C into a numeric array of size 80-by-90-by-19-by-20
M = cell2mat(C);

%# average the 20 "slices" to get a 80-by-90-by-19 array
M = mean(M,4);

1
非常干净的代码。虽然cell2mat会影响性能。在我的电脑上,它比循环慢4倍。 - angainor

2
假设我理解您的意思正确,您可以按照以下方式完成您想要的操作(注释会逐步解释我所做的内容):
% allocate space for the output
R = zeros(80, 90, 19);

% iterate over all 19 sets
for i=1:19
    % extract ith set of 20 matrices to a separate cell
    icell = {C{:,1,i}};

    % concatenate all 20 matrices and reshape the result
    % so that one matrix is kept in one column of A 
    % as a vector of size 80*90
    A = reshape([icell{:}], 80*90, 20);

    % sum all 20 matrices and calculate the mean
    % the result is a vector of size 80*90
    A = sum(A, 2)/20;

    % reshape A into a matrix of size 80*90 
    % and save to the result matrix
    R(:,:,i) = reshape(A, 80, 90);    
end

您可以跳过对icell的提取,直接将第i组20个矩阵连接起来。
A = reshape([C{:,1,i}], 80*90, 20);

为了更清晰明了,我只是在这里做了一些操作。

上述步骤可以通过以下arrayfun调用更简洁地表达(但肯定更加难以理解!):

F = @(i)(reshape(sum(reshape([C{:,1,i}], 80*90, 20), 2)/20, 80, 90));
R = arrayfun(F, 1:19, 'uniform', false);
R = reshape([R2{:}], 80, 90, 19);

匿名函数 F 实际上只执行循环的一次迭代。每组矩阵都会调用 arrayfun 19 次。我建议您继续使用循环。


我建议使用mean而不是sum(x)/n - Jonas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接