在许多应用中,MATLAB的accumarray功能强大得难以置信我的问题是,要应用于输入的Myaccumarray函数有三个输出,accumarray只能处理标量输出例如,我想做这样的事情:

subs = [1;2;4;2;4;5];
vals = [1;1;1;2;5;1];
accumarray(subs, vals, [], @(x)[min(x),mean(x),max(x)],0)

并有accumarray返回:
1.0000    1.0000         0    1.0000    1.0000
1.0000    1.5000         0    3.0000    1.0000
1.0000    2.0000         0    5.0000    1.0000

我想我可以运行accumarray三次,但是我的功能很慢,运行accumarray一次会比运行三次快得多我是不是刚洗完澡?

最佳答案

您可以欺骗使匿名函数输出一个单元格数组而不是一个值这样,accumarray将为您提供矩阵的单元格数组完成后,可以将所有矩阵连接到单个矩阵注意,您提出的匿名函数将minmaxmean作为行向量,但是您的预期结果是列向量因此我在你的匿名函数中转换了这个。
我们必须考虑的问题是填充值指定的填充值必须是标量因此,您可以通过省略此项来作弊,但是现在您的输出将在单元格中包含空矩阵,而不是结果中用0填充的行解决这个问题的方法是找到所有空单元格,用一行0替换它们,然后在完成后将它们拼凑在一起要确定accumarray输出中的哪些行将为空,可以将cellfunisempty结合使用,这样我们就可以看到结果中的哪些元素是空的一种更简洁的方法是,首先预先分配zeros的矩阵,然后只填充与accumarray输出中的非空位置相对应的行来完成:

subs = [1;2;4;2;4;5];
vals = [1;1;1;2;5;1];
out = accumarray(subs, vals, [], @(x){[min(x),mean(x),max(x)].'});
ind_empty = cellfun('isempty', out);
out_final = zeros(3, numel(out));
out_final(:, ~ind_empty) = cat(2, out{:});

注意cat的用法,它是在指定的维度中将矩阵连接在一起执行out{:}会产生一个称为comma-separated list的结果,因此它相当于将accumarray输出的每一列作为单独的参数放入cat中,这样我们最终会将所有列拼凑成一个单独的矩阵,但我是以这样一种方式切入输出的,即我们只填充那些不为空的位置。
根据你的测试输入,我匹配你得到的结果:
>> out_final

out_final =

    1.0000    1.0000         0    1.0000    1.0000
    1.0000    1.5000         0    3.0000    1.0000
    1.0000    2.0000         0    5.0000    1.0000

但是,如果我可以诚实地说,如果您确定只有三个值要放入accumarray中,那么在完成后只调用三次然后连接所有值可能会更快我认为它更具可读性,而且能清楚地说明你在做什么像我对上面的单元数组所做的那样,需要你真正了解MATLAB的工作原理。

10-08 00:40