滑动平均是时间序列平滑技术,php中可用固定窗口队列实现;基础版用数组切片+array_sum,优化版用增量更新避免重复求和;支持键值时间序列,需先ksort排序再提取数值;注意窗口大小、浮点精度及内存友好性。

滑动平均(Moving Average)是一种常用的时间序列平滑技术,PHP 中可通过维护一个固定长度的窗口队列来高效实现。核心是每次新数据加入时,移除最老数据、加入最新数据,并重新计算平均值;更优做法是用“增量更新”避免重复求和。
基础版本:数组切片 + array_sum
适合数据量小、对性能不敏感的场景。每次取最近 n 个元素,直接求平均:
function simpleMovingAverage($data, $window) {
$result = [];
$len = count($data);
for ($i = $window - 1; $i < $len; $i++) {
$slice = array_slice($data, $i - $window + 1, $window);
$result[] = array_sum($slice) / $window;
}
return $result;
}
// 示例:$data = [1,2,3,4,5,6]; simpleMovingAverage($data, 3) → [2,3,4,5]
优化版本:增量更新(推荐)
避免重复加总,时间复杂度从 O(n×w) 降为 O(n)。只需记录当前窗口和、窗口大小,每次减去退出值、加上进入值:
function movingAverageStream($window) {
$buffer = [];
$sum = 0;
return function($newVal) use (&$buffer, &$sum, $window) {
if (count($buffer) >= $window) {
$sum -= array_shift($buffer); // 移除最老值
}
$buffer[] = $newVal;
$sum += $newVal;
return $sum / count($buffer);
};
}
<p>// 使用示例:
$ma = movingAverageStream(3);
echo $ma(1); // 1
echo $ma(2); // 1.5
echo $ma(3); // 2
echo $ma(4); // 3 ← [2,3,4] 平均值</p>支持键值时间序列(如带时间戳的数据)
若输入是 [timestamp => value] 形式,需按时间排序后滑动。可先提取有序数值数组,再套用上述逻辑:
立即学习“PHP免费学习笔记(深入)”;
- 用 ksort() 确保时间戳升序
- 用 array_values() 提取纯数值序列
- 传入优化版函数处理
- 若需对齐原始时间戳,结果可与对应窗口末尾时间配对
注意事项
- 窗口大小应为正整数,首次不足窗口时可返回部分平均或 null,按需处理
- 浮点精度问题:PHP 默认浮点运算,如需高精度可用 bcadd() + 手动除法
- 内存友好:增量版只存 $window 个值,适合实时流式计算
- 扩展性:可轻松改造成加权滑动平均(如指数移动平均 EMA),只需调整权重逻辑









