从 numpy 数组中删除类似方波的伪影

Posted

技术标签:

【中文标题】从 numpy 数组中删除类似方波的伪影【英文标题】:Removing square wave like artifacts from numpy array 【发布时间】:2018-08-05 06:40:24 【问题描述】:

我有一个 numpy 数组,它基本上是 excel 表中的一个数据列。该数据是通过低通 10 Hz 滤波器 DAS 获得的,但由于某些模糊性,它包含类似方波的伪影。现在必须以 0.4 Hz 高通巴特沃斯滤波器过滤数据,我通过 scipy.signal 进行过滤。但在应用高通滤波器后,方波状伪影变成尖峰。将 scipy.median 应用于它时,我无法成功过滤尖峰。我应该尝试什么?

下图为原始数据。

下图显示了应用 0.4 Hz 的高通滤波器,然后是 3 阶中值滤波器

即使是 51 阶的中值滤波器也没有用。

【问题讨论】:

阈值可能会起作用。只需将原始数据中 3-sigma 之外的任何内容丢弃即可。 请修复您的标签 除方形区域外的数据的 Sigma 约为 1.6,但方形区域约为 26。恐怕阈值高于 v 3 乘以 26 不会有任何帮助。 26x3 = 78。它们看起来不错。也许将其降低到 2.5 或迭代地进行 你能提供数据吗? 【参考方案1】:

如果您的输入总是有明显的异常值,我建议使用迭代过滤方法。

这里是您的数据以及平均值、1-sigma、2-sigma 和 3-sigma 线:

我会首先从平均值中删除高于和低于 2-sigma 的所有内容。由于这会收紧分布,我建议一遍又一遍地进行迭代,直到未修剪数据的大小保持不变。我建议以几何方式增加阈值以避免修剪“好”数据。最后,你可以用余数的平均值或类似的东西来填补缺失的点。

这是一个示例实现,没有任何优化尝试:

data = np.loadtxt('data.txt', skiprows=1)
x = np.arange(data.size)
loop_data = data
prev_size = 0
nsigma = 2
while prev_size != loop_data.size:
    mean = loop_data.mean()
    std = loop_data.std()
    mask = (loop_data < mean + nsigma * std) & (loop_data > mean - nsigma * std)
    prev_size = loop_data.size
    loop_data = loop_data[mask]
    x = x[mask]
    # Constantly expanding sigma guarantees fast loop termination
    nsigma *= 2

# Reconstruct the mask
mask = np.zeros_like(data, dtype=np.bool)
mask[x] = True
# This destroys the original data somewhat
data[~mask] = data[mask].mean()

这种方法可能并非在所有情况下都是最佳的,但我发现它在大多数情况下都相当稳健。有很多可调整的参数。您可能希望将增加因子从 2 更改,甚至使用线性增加而不是几何增加(尽管我尝试了后者,但它确实效果不佳)。您也可以使用 IQR 代替 sigma,因为它对异常值更稳健。

这是结果数据集的图像(删除部分为红色,原始部分为虚线):

另一个令人感兴趣的工件:这里是显示修剪进程以及它如何影响截止点的数据图。绘图显示数据,切割部分为红色,其余部分为 n-sigma 线。标题显示了 sigma 缩小了多少:

【讨论】:

以上是关于从 numpy 数组中删除类似方波的伪影的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL ES 顶点数组对象和奇怪的伪影

QWidgets 留下以前油漆的伪影

Matlab来自正弦波的方波

如何从数组的numpy数组中删除外部数组[重复]

Numpy - 从一维数组中删除最后一个元素的最佳方法?

使用 ggplot2 绘制 shapefile 的伪影