【问题标题】:MATLAB compute average value corresponding to each column number in matrix?MATLAB计算矩阵中每个列号对应的平均值?
【发布时间】:2016-05-01 10:33:52
【问题描述】:

假设我有以下数组:

A=[1 2
   1 4
   2 6
   3 5
   5 7
   1 9
   2 7];

在 MATLAB 中,自动获取一个矩阵的最有效(最好是单线)方法是什么,该矩阵包含第一列中每个唯一元素的第二列元素的平均值?上面A 的结果是:

B=[1 mean([2 4 9])
   2 mean([6 7])
   3 mean([5])
   5 mean([7])];

提前致谢!

【问题讨论】:

    标签: arrays matlab


    【解决方案1】:

    unique 可以生成第一列,而配备 mean 函数的强大 accumarray 将计算第二列(在这种情况下,nonzeros 被称为不存在的索引,例如 4):

    >> B = [unique(A(:,1)),nonzeros(accumarray(A(:,1),A(:,2),[],@mean))]
    B =
        1.0000    5.0000
        2.0000    6.5000
        3.0000    5.0000
        5.0000    7.0000
    

    正如dan-man 在 cmets 中所指出的,上述方法仅在第一列始终具有整数值的情况下才有效(我想我从给定的示例中暗示了这个用例;抱歉)。你可以使用unique来绕过这个缺点:

    [Aunq,~,Aind] = unique(A(:,1));
    B = [Aunq,accumarray(Aind,A(:,2),[],@mean))];
    

    进一步指出,由于accumarray在内部的工作方式,直接调用mean不如直接执行计算效率高:

    B = [Aunq,accumarray(Aind,A(:,2),[],@sum)./accumarray(Aind,1,[],@sum)]
    

    【讨论】:

    • accumarray 如果A(:,1) 包含除小的正整数以外的任何内容,则将失败。但是您可以通过将A(:,1) 替换为unique(A(:,1)) 的第三个输出来轻松解决这个问题。然后你也可以放弃包装 nonzeros 电话。
    • 另外,如果性能相关,我建议将 accumarray(...@mean) 替换为 accumarray(...,@sum) ./ accumarray(...1,[],@sum),即手动计算总和和计数并进行除法。上次我检查这要快得多,因为 accumarray 没有针对与 @mean 一起使用进行优化。
    • 非常感谢大家!对我帮助很大。
    【解决方案2】:
    B=[];for k=unique(A(:,1)).';B=[B;k sum((A(:,1)==k).*A(:,2))/sum((A(:,1)==k))];end
    

    【讨论】:

      猜你喜欢
      • 2014-03-15
      • 1970-01-01
      • 2021-07-24
      • 1970-01-01
      • 2018-12-02
      • 2017-08-21
      • 2018-09-23
      • 1970-01-01
      • 2015-04-13
      相关资源
      最近更新 更多