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

时间序列平台型离群点识别:非等值平台检测问题及方案问询

识别时间序列中近零斜率平台区域的方法与库

针对你用np.diff无法识别非完全等值近零斜率平台的问题,以下是几种实用的方法和可用库:

1. 滑动窗口斜率阈值法(Numpy/Scipy实现)

直接针对斜率近零这个平台核心特征,用滑动窗口计算局部线性拟合的斜率,筛选斜率绝对值低于阈值且长度达标的连续区间:

import numpy as np
from scipy.stats import linregress

def find_plateaus_slope_window(F, min_length=5, slope_threshold=0.01, window_size=11):
    n = len(F)
    is_plateau = np.zeros(n, dtype=bool)
    
    for i in range(n - window_size + 1):
        window = F[i:i+window_size]
        x = np.arange(window_size)
        slope, _, _, _, _ = linregress(x, window)
        if abs(slope) <= slope_threshold:
            is_plateau[i:i+window_size] = True
    
    # 提取连续达标区间
    diff = np.diff(np.concatenate(([0], is_plateau.astype(int), [0])))
    starts = np.where(diff == 1)[0]
    ends = np.where(diff == -1)[0]
    return np.array([[s, e] for s, e in zip(starts, ends) if e - s >= min_length])

2. Pandas Rolling窗口统计

利用Pandas的滚动窗口功能,结合数据波动(标准差)和斜率双重条件筛选平台,更鲁棒:

import pandas as pd
import numpy as np
from scipy.stats import linregress

def rolling_slope(window):
    x = np.arange(len(window))
    return linregress(x, window)[0]

def find_plateaus_pandas(series, min_length=5, slope_tol=0.01, std_tol=0.1, window=11):
    rolling_slopes = series.rolling(window=window).apply(rolling_slope, raw=True)
    rolling_std = series.rolling(window=window).std()
    
    # 标记符合条件的点
    is_plateau = (abs(rolling_slopes) <= slope_tol) & (rolling_std <= std_tol)
    is_plateau = is_plateau.fillna(False)
    
    # 提取连续区间
    diff = np.diff(np.concatenate(([0], is_plateau.astype(int), [0])))
    starts = np.where(diff == 1)[0]
    ends = np.where(diff == -1)[0]
    return np.array([[s, e] for s, e in zip(starts, ends) if e - s >= min_length])

3. Scipy信号处理工具

用Scipy的信号平滑函数先降噪,再通过一阶导数绝对值筛选近零斜率区域,适合噪声较多的时间序列:

import numpy as np
from scipy.ndimage import uniform_filter1d

def find_plateaus_scipy(F, min_length=5, slope_tol=0.01, smoothing=11):
    smoothF = uniform_filter1d(F, size=smoothing)
    dF = np.gradient(smoothF)
    smooth_dF = uniform_filter1d(dF, size=smoothing)
    
    # 标记斜率近零的点
    is_plateau = np.abs(smooth_dF) <= slope_tol
    
    # 提取连续区间
    diff = np.diff(np.concatenate(([0], is_plateau.astype(int), [0])))
    starts = np.where(diff == 1)[0]
    ends = np.where(diff == -1)[0]
    return np.array([[s, e] for s, e in zip(starts, ends) if e - s >= min_length])

4. 时间序列特征库Tsfresh

Tsfresh内置大量时间序列特征提取函数,可直接调用或自定义特征来检测平台:

  • 利用内置特征:比如longest_strike_below_mean(连续低于均值的最长段)、mean_abs_change(平均绝对变化率)等,筛选变化率极低的连续段
  • 自定义特征:编写函数检测局部斜率近零的区间,结合Tsfresh的批量处理能力

对你现有代码的改进建议

你当前用二阶导数检测的思路可以调整为一阶导数近零(平台的核心是斜率为0,一阶导数直接反映斜率),同时替换区间检测逻辑,避免依赖np.diff(smalld2F)的突变检测,改用连续True段的提取方式(如上述代码中的diff方法),能更准确捕捉非完全等值的平台区域。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 04:05:12