SciPy medfilt错误的复苏

2024-05-16 09:59:22 发布

您现在位置:Python中文网/ 问答频道 /正文

嗨,Python爱好者!

我目前正在研究信号滤波,并决定使用SciPy。没什么特别的,只是日常工作的自动化。

所以,这是密码

from scipy.signal import medfilt
print(medfilt([2,6,5,4,0,3,5,7,9,2,0,1], 5))

但问题是返回的序列计算错误

SciPy: [ 2. 4. 4. 4. 4. 4. 5. 5. 5. 2. 1. 0.]
Me   : [ 5. 4.5 4. 4. 4. 4. 5. 5. 5. 2. 1.5 1.]

似乎,包的开发人员搞乱了一个细节。当孔径(以SciPy表示的核)大于要分析的窗口时,还有另一个过滤规则。

例如,使用kernel=5过滤的[2, 6, 5]子序列具有中位数5而不是SciPy计算的2,不是吗?同样地,如果子序列[2,6,5,4]的中介是5和4,我们需要取它们之间的平均值,所以,中值是4.5。

有人能给我解释一下在那种情况下谁得到了正确的结果吗?


Tags: fromimport密码signal信号开发人员序列scipy
1条回答
网友
1楼 · 发布于 2024-05-16 09:59:22

我相信你和西皮都有正确的结果。不同的是在边界上发生了什么,但是我相信你和SciPy都做出了正确的选择。

问题是,当滑动窗口位于边缘时,没有有效的数据可用于填充滑动窗口时,会发生什么情况。

您选择了滑动窗口有效部分的中值,这是有意义的,但可能会增加一些偏差,因为与所有其他点相比,边缘点的比例过高。

相反,SciPy选择通过填充零来扩展信号的任意边。所以,在边界上,SciPy本质上是在计算

>>> np.median([0, 0, 2, 6, 5])
2.0
>>> np.median([0, 2, 6, 5, 4])
4.0
>>> np.median([9, 2, 0, 1, 0])
1.0
>>> np.median([2, 0, 1, 0, 0])
0.0

SciPy这样做的原因几乎肯定与速度有关:它经过多次优化来完成相同的任务,而且对于一大堆5元素数组优化median要比对于一大堆5元素数组以及两个4元素数组和两个3元素数组优化它容易得多。当然有一个论点是不应该用零填充,而应该用边界值填充,但是应该注意,没有一个边界策略是完美的;处理边界问题的理想方法将取决于您的特定信号。

如果您看到Wikipedia's description of median filters,它们会在任意一条边上用边上的值填充来扩展信号,这似乎也是合理的。他们还注意到处理边界问题的其他三种方式:

  • 避免处理边界,无论之后是否裁剪信号边界。
  • 从信号中的其他位置获取条目。例如,对于图像,可以选择来自远水平或垂直边界的条目。
  • 缩小边界附近的窗口,以便每个窗口都已满(正如您所做的那样)

最后,你真的需要尝试不同的选择,看看什么最适合你的信号。这种滤波的一个核心假设是,你的信号会非常大,而边界问题永远不会那么关键(因为大多数信号不存在于边界上)。不过,如果SciPy允许您选择它在边界上应该做什么,那就太好了!

相关问题 更多 >