【问题标题】:How to calculate a weighted mean?如何计算加权平均值?
【发布时间】:2010-10-04 04:07:49
【问题描述】:

我的语言是 PHP,但算法应该是相当通用的。

我有一个关联数组(比方说)评级和评级的次数。

$ratings = array(
    1 => 1,
    2 => 3,
    3 => 6,
    4 => 3,
    5 => 3
);

这相当于:[1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5],但考虑到我正在使用的数字,从第一种形式转换为第二种形式效率非常低。

计算上述数字的平均值的算法是什么?

【问题讨论】:

    标签: php algorithm statistics


    【解决方案1】:

    我怀疑我可以击败公认的答案,但我发现内置循环函数比脚本循环运行得更快。不确定对 $multiply 的调用将如何优化。如果这真的很慢,那么我希望有人会在评论中指出它。

    function multiply( $k , $v ) { return $k * $v; }
    return array_sum( array_map( 'multiply' , array_keys($ratings) , $ratings ) ) / array_sum( $ratings );
    

    【讨论】:

    • +1 用于 PHP 实现。至于性能:使用 10000 个“点”数组,每个点数在 0 到 255 之间,平均 100 次:您的函数:4.294s,接受的解决方案:3.45115s
    • 如此接近!当我自己对其进行基准测试时,它实际上并没有那么接近,但仍在运行中。我注意到你编辑了我不正确的 lambda 函数语法,如果你有 PHP 5.3,你应该尝试使用在 array_map 中内联定义的匿名函数。
    【解决方案2】:

    这不行吗?

    $total = 0;
    $sum = 0;
    foreach ($ratings as $k => $v) {
      $total += $k * $v;
      $sum += $v;
    }
    echo $total / $sum;
    

    编辑:好吧,我看起来很傻,因为有人打败了我。哦,好吧。

    【讨论】:

    • 是的,我注意到了——这太疯狂了。
    【解决方案3】:

    试试这个:

    $total = 0;
    $count = 0;
    foreach($ratings as $number=>$frequency) {
      $total += $number * $frequency;
      $count += $frequency;
    }
    return $total / $count;
    

    【讨论】:

    • 您可能需要在返回行中将其中一个数字转换为 double,我不记得 PHP 是否进行整数除法。
    • 如果有“决斗接受的答案”按钮,我会点击这里:)
    • 恕我直言,这不是“平均”计算,而是“平均”计算。由于答案被接受,我猜 nickf 正在寻找“平均”计算
    • 最后一行应该是return $count ? ($total / $count) : 0;
    • 我认为这行不通。我使用了一个键为 1 到 5 的数组,并且在 5 键中有 15 票。它产生的平均值为 4。在 5 键中有 15 票。没有意义。
    猜你喜欢
    • 1970-01-01
    • 2021-11-24
    • 2017-01-06
    • 2016-05-10
    • 2015-04-02
    • 2012-06-14
    • 2016-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多