Мне нужно вычислить среднее увеличение значений массива, и я создал небольшой скрипт, который работает, но я хотел бы знать, если:
Допустим, у меня такой массив:
$array = array(5,10,15,10,0,15);
Давайте также предположим, что каждый элемент массива составляет 1 день, а значение – это некоторый счетчик за этот день. Я хотел бы рассчитать среднее увеличение / уменьшение счетчика.
То, что я сделал, зацикливается через массив и изменило значения так, чтобы текущий элемент = текущий элемент – предыдущий элемент, каким образом я остаюсь с массивом, который будет выглядеть так:
$array = array(5,5,-5,-10,15);
Затем я вычисляю среднее значение по нормали, которое в этом примере дало бы мне 2-х средний прирост на ежедневной основе.
Код здесь:
$array = array(5,10,15,10,0,15); $count = count($array); for($i=0;$i<$count;$i++) { if($i==0) { $value = $array[$i]; unset($array[$i]); } else { $tmp = $array[$i]; $array[$i] -= $value; $value = $tmp; } } echo array_sum($array) / count($array);
с$array = array(5,10,15,10,0,15); $count = count($array); for($i=0;$i<$count;$i++) { if($i==0) { $value = $array[$i]; unset($array[$i]); } else { $tmp = $array[$i]; $array[$i] -= $value; $value = $tmp; } } echo array_sum($array) / count($array);
Правильно ли здесь логика, и есть ли более эффективный способ сделать это, может быть, без цикла?
Заранее спасибо 🙂
EDIT: обновленный код для учетной записи для исключения первого значения
Как насчет этого:
function moving_average($array) { for ($i = 1; $i < sizeof($array); $i++) { $result[] = $array[$i] - $array[$i-1]; } return array_sum($result)/count($result); }
Попробуй это :
$array = array(5,10,15,10,0,15); $array2 = $array; array_pop($array2); array_unshift($array2, $array[0]); $subtracted = array_map(function ($x, $y) { return $y-$x; } , $array2, $array); array_shift($subtracted); /// Comment this if you want six values with 0 as first value echo array_sum($subtracted) / count($subtracted);
Для вас это классный однострочный:
$days = array(5, 10, 15, 10, 0, 15); $deltas = array_slice(array_map(function($day1, $day2) { return $day2 - $day1; }, $days, array_slice($days, 1)), 0, -1); var_dump(array_sum($deltas) / count($deltas));
$array = array(5,10,15,10,0,15); list($prevVal) = array_slice($array, 1); array_walk($array, function($value, $key, &$prevVal) use(&$array){ if ($key==0) { return; } $array[$key] = ($value - $prevVal); $prevVal = $value; }, $prevVal); echo array_sum($array) / count($array);
Выходы 1.6666666666667 in float (3.0994415283203E-5)