You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas中实现类似MATLAB的两端可伸缩窗口移动平均?

问题解答

方法名称

你说的这种两端逐步调整窗口大小的滑动平均,叫做自适应窗口大小的中心移动平均(MATLAB中smooth(signal, 9, 'moving')的核心逻辑就是中心移动平均,在首尾数据不足时自动缩小窗口,避免NaN和滞后)。

Pandas/NumPy/SciPy中的实现

Pandas没有直接内置这个功能,但可以通过自定义函数快速实现,逻辑和MATLAB完全一致:

import pandas as pd
import numpy as np

def matlab_style_smooth(s, window_size):
    n = len(s)
    result = np.zeros(n)
    half_win = (window_size - 1) // 2  # 窗口大小为9时,half_win=4
    
    for i in range(n):
        # 计算当前位置的实际窗口大小:开头逐步增大,末尾逐步缩小,中间保持设定的window_size
        current_win_size = min(2*i + 1, window_size, 2*(n - 1 - i) + 1)
        # 确定窗口的起止索引
        start_idx = i - (current_win_size - 1) // 2
        end_idx = start_idx + current_win_size
        # 计算窗口内的均值
        result[i] = s.iloc[start_idx:end_idx].mean()
    
    return pd.Series(result, index=s.index)

# 使用示例:假设你的数据列是df['signal']
df['smoothed_signal'] = matlab_style_smooth(df['signal'], 9)

如果数据量很大,循环效率不够,可以用卷积逻辑优化:

def fast_smooth(s, window_size):
    n = len(s)
    half = (window_size - 1) // 2
    # 生成每个位置的窗口大小数组
    win_sizes = np.array([min(2*i+1, window_size, 2*(n-1-i)+1) for i in range(n)])
    # 对原始数据补边,方便生成滑动窗口
    padded = np.pad(s.values, (half, half), mode='constant', constant_values=np.nan)
    windowed = np.lib.stride_tricks.sliding_window_view(padded, window_size)
    
    means = []
    for i in range(n):
        win = windowed[i]
        # 根据位置截取窗口内的有效数据
        if i < half:
            valid = win[:win_sizes[i]]
        elif i > n - 1 - half:
            valid = win[-win_sizes[i]:]
        else:
            valid = win
        means.append(np.nanmean(valid))
    return pd.Series(means, index=s.index)

SciPy中没有直接对应这个逻辑的函数,scipy.signal.savgol_filter虽能实现平滑,但它是基于多项式拟合的滤波,和你需要的简单移动平均逻辑不一致。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 19:29:53