You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Scala数组平滑处理:如何保持输出数组长度与输入一致?

解决数组平滑后长度与输入一致的问题

这问题太常见啦!用滑动窗口做数组平滑时,首尾元素因为凑不齐完整窗口,导致输出比输入短,确实挺闹心的。给你几个实用的解决思路,按需选就行:

方案1:首尾直接保留原数据

最简单粗暴的办法——开头前窗口大小-1个元素直接用原数据,中间部分正常用滑动窗口计算平滑值,这样总长度就和输入完全一致了。

举个Python的例子(以窗口大小3的均值平滑为例):

def smooth_array(arr, window_size=3):
    smoothed = []
    # 处理开头:直接取原数据,直到窗口能完全覆盖
    for i in range(min(window_size - 1, len(arr))):
        smoothed.append(arr[i])
    # 处理中间:用完整窗口计算均值
    for i in range(window_size - 1, len(arr)):
        window = arr[i - window_size + 1 : i + 1]
        smoothed.append(sum(window) / len(window))
    return smoothed

比如输入[1,2,3,4,5],窗口3的话,开头前2个元素直接保留,中间3个用窗口计算,输出就是[1,2,2,3,4](对应窗口[1,2,3]得2,[2,3,4]得3,[3,4,5]得4),长度和输入一致。

方案2:边界填充后再平滑

如果不想首尾用原数据,想让所有元素都是平滑后的结果,可以先给数组的边界做填充,让滑动窗口能覆盖到首尾。常见的填充方式有这几种:

  • 镜像填充:把首尾元素镜像复制(比如[a,b,c,d]填充成[a,a,b,c,d,d]),避免边界值突变
  • 重复填充:直接重复首尾元素(和镜像效果类似,适合单元素重复)
  • 零填充:首尾补0,不过这种可能会拉低首尾的平滑值,只适合特定场景

这里给你镜像填充的Python示例:

def smooth_array_with_pad(arr, window_size=3):
    pad_size = window_size // 2
    # 镜像填充首尾:把开头pad_size个元素反转后加在前面,结尾pad_size个元素反转后加在后面
    padded_arr = arr[:pad_size][::-1] + arr + arr[-pad_size:][::-1]
    smoothed = []
    # 遍历原数组的每个位置,用填充后的窗口计算平滑值
    for i in range(pad_size, len(padded_arr) - pad_size):
        window = padded_arr[i - pad_size : i + pad_size + 1]
        smoothed.append(sum(window) / len(window))
    return smoothed

这个方案输出的每个元素都是平滑后的结果,比如输入[1,2,3,4,5],填充后是[1,1,2,3,4,5,5],计算后输出[1.333,2,3,4,4.666],长度和输入一致,效果更连贯。

方案3:动态调整窗口大小

另一种思路是,对于首尾的元素,动态缩小窗口大小,尽可能利用周围的元素计算平滑值。比如第一个元素用窗口大小1(就是自己),第二个用窗口大小2,直到达到设定的窗口大小后保持;结尾则反过来,逐渐缩小窗口大小。

示例代码:

def smooth_array_dynamic_window(arr, window_size=3):
    smoothed = []
    n = len(arr)
    half_window = window_size // 2
    for i in range(n):
        # 计算当前窗口的有效起始和结束索引,避免越界
        start = max(0, i - half_window)
        end = min(n - 1, i + half_window)
        # 取窗口内的元素计算均值
        window = arr[start:end+1]
        smoothed.append(sum(window) / len(window))
    return smoothed

输入[1,2,3,4,5]的话,输出是[1.5,2,3,4,4.5],每个元素都用了尽可能多的周围数据,兼顾了长度一致和平滑效果。

怎么选?

  • 追求最简单实现,不介意首尾用原数据 → 选方案1
  • 希望所有元素都是平滑结果,效果连贯 → 选方案2(优先镜像填充)
  • 想要首尾的平滑值尽可能合理利用周围数据 → 选方案3

内容的提问来源于stack exchange,提问作者lserlohn

火山引擎 最新活动