평균 구하는 함수 모음집.

예외처리 같은 건 생략하고 알고리즘만 구현해 놓은 것.

class Avg
{
    // 산술평균 (arithmetic)
    public static function mean($a)
    {
        return array_sum($a) / count($a);
    }

    // 중앙값 (median)
    public static function median($a)
    {
        sort($a, SORT_NUMERIC);
        $cnt = count($a);
        $median_pos = floor($cnt / 2);
        $median = $a[$median_pos];
        if ($cnt % 2 === 0) $median = ($median + $a[$median_pos-1]) / 2;

        return $median;
    }

    // 최빈값 (mode)
    public static function mode($a)
    {
        $b = array_count_values($a);
        arsort($b, SORT_NUMERIC);

        return current(array_keys($b));
    }

    // midrange
    public static function midrange($a)
    {
        sort($a, SORT_NUMERIC);

        return ($a[0] + $a[count($a)-1]) / 2;
    }

    // 절단평균 (trimmed mean)
    // 양쪽 끝 1%씩 잘라내려면 0.01, 10% = 0.1 ...
    public static function trimmean($a, $trim=0.01)
    {
        $trim_count = floor($trim * count($a));
        if ($trim_count > 0) {
            sort($a, SORT_NUMERIC);
            for ($i=0; $i<$trim_count; $i++) {
                array_shift($a);
                array_pop($a);
            }
        }

        return self::mean($a);
    }

    // 기하평균 (geometric)
    public static function geometricMean($a)
    {
        $mul = 0;
        foreach ($a as $i=>$v) {
            $mul = ($i === 0) ? $v : $mul * $v;
        }

        return pow($mul, 1/count($a));
    }

    // 조화평균 (harmonic)
    public static function harmonicMean($a)
    {
        $sum = 0;
        foreach ($a as $v) $sum += 1 / $v;

        return (1 / $sum) * count($a);
    }

    // 가중평균 (weighted)
    public static function weightedMean($a, $w)
    {
        $b = array();
        foreach ($a as $k=>$v) $b[] = $v * $w[$k];

        return self::mean($b);
    }
}
 
// 평균을 구하고자 하는 배열
$a = array(1,2,3,4,4,5,6,7,8,9,10);

// 각종 평균을 출력해보자
printf("MEAN     = %.1f\n", Avg::mean($a));
printf("MEDIAN   = %.1f\n", Avg::median($a));
printf("MODE     = %.1f\n", Avg::mode($a));
printf("MIDRANGE = %.1f\n", Avg::midrange($a));
printf("TRIMMEAN(10%%)  = %.1f\n", Avg::trimmean($a, 0.1));
printf("TRIMMEAN(30%%)  = %.1f\n", Avg::trimmean($a, 0.3));
printf("GEOMETRIC MEAN = %.1f\n", Avg::geometricMean($a));
printf("HARMONIC MEAN  = %.1f\n", Avg::harmonicMean($a));
$w = array(0.1, 0.3, 0.1, 0.9, 0.7, 0.2, 0.7, 0.1, 0.2, 0.3, 0.4);
printf("WEIGHTED MEAN  = %.1f\n", Avg::weightedMean($a, $w));

/*
결과는 아래와 같음

MEAN     = 5.4
MEDIAN   = 5.0
MODE     = 4.0
MIDRANGE = 5.5
TRIMMEAN(10%)  = 5.3
TRIMMEAN(30%)  = 5.2
GEOMETRIC MEAN = 4.5
HARMONIC MEAN  = 3.5
WEIGHTED MEAN  = 2.0
*/










Posted by bloodguy
,