【问题标题】:De-spiking a non-periodic signal去尖峰非周期信号
【发布时间】:2018-02-12 17:35:34
【问题描述】:

我正在处理来自仪器的一组数据(x={time},y={measure}),但有时来源会导致数据出现峰值,从而导致绘图不正确,并可能导致计算最大值和最小值等特征时出现错误。

所以我需要从我的数据中删除这些尖峰,例如图像中被红色圆圈包围的尖峰:

我发现 this example 用于去尖峰,但我不知道如何反转信号(以及它在非对称信号上是否正确),我认为这只是为了检测尖峰,我需要删除他们进行拟合等操作...

我需要帮助来了解是否有更好的方法来完成我的任务,或者我是否只需根据我的情况调整上面的示例(在这种情况下,我需要帮助,因为我不知道该怎么做)。

【问题讨论】:

  • 可能是最大导数条件,看起来“尖峰”是单个样本?
  • 在这种情况下,尖峰不是单个样本,而是与其他样本相比的一小部分。无论如何,我会尝试使用这个平滑过滤器和阈值,@MadPhysicist 你能轻轻地给我链接一些关于这个操作的指南或示例吗?非常感谢!
  • 这是signal-processing 编程端的合法主题问题,不应关闭。
  • 它看起来确实像一个有噪音的传感器。在您过滤之前,请知道过滤会添加它自己的错误(来自延迟)。对于这样的问题,我建议将其分为两部分(异常检测和异常修复)。为了最大限度地减少错误,异常数据可以替换为段的自适应复制。这样,您就可以对未检测到异常的异常区域和真实数据进行最佳猜测。

标签: python plot signal-processing


【解决方案1】:

您可以按照以下一组步骤来估计峰的位置:

  1. 平滑数据。任何数量的过滤器都可用于此。一个很好的起点是scipy cookbook 中描述的smooth 函数。您可以选择适当的参数,例如窗口大小:

    baseline = smooth(data, ...)
    
  2. 将平滑后的数据视为基线,有点像在没有已知拟合函数的情况下的最佳拟合线。从数据中减去基线:

    noise = data - baseline
    
  3. 结果本质上是对伪拟合噪声的粗略估计。设置噪声过多部分的阈值和斩波:

    threshold = 3.0 * np.std(noise)
    mask = np.abs(noise) > threshold
    

这里有很多配置选项可供使用:平滑过滤器类型和窗口大小、阈值因子甚至指标。例如,您可以使用 IQR 或完全不同的东西来代替标准差。您对蒙面点的处理也完全取决于您。常见的选项是完全丢弃或替换为基线值。

【讨论】:

  • 感谢您的回答,该解决方案似乎有效,但我遇到了一个问题,在平滑函数之后,基线的点数与数据不同;这正常吗?我可以说这是有效的,因为我在使用 x=plt.linspace(1,len(baseline),len(baseline)) 的图表中平滑后打印了基线,但是为了执行 数据 - 基线 我需要它们具有相同数量的样本。
  • 我认为这是一个单独的问题。我不知道你到底做了什么,所以很难说出了什么问题。
  • 听起来您使用掩码将数据基线点提取到另一个数组中。如果是这样,则新数组更小。然后,您需要以类似的方式屏蔽绘图中的“x”值数组 - 基本上保留原始 X、Y 对和新过滤的 X、Y 对的一对一映射。
【解决方案2】:

您想要删除一些异常值,并且有很多方法可以做到这一点。主要目标是检测它们,并根据相邻样本进一步用估计值替换它们。

最简单,可以说是最有效的方法是找到连续样本的运行差异,并将它们与某个预定阈值进行比较。在这里,您必须小心确定阈值的大小,因为这将决定您算法的灵敏度和准确性。

第二种解决方案可能是简单地使用低通滤波器,但我建议使用线性相位 filtfilt scipy.signal.filtfilt。

可以使用另一种过滤器,中值过滤器可能是最好的选择:scipy.signal.medfilt。

我希望这能回答您的问题,并且您将能够找到适合您情况的滤波器系数。

【讨论】:

  • 就特定用例同意scipy.signal.medfilt
猜你喜欢
  • 2017-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-03
相关资源
最近更新 更多