过滤(平滑)连续流数据的最有效方法是什么

时间:2017-04-15 22:54:26

标签: python scipy signal-processing

我正在制作自己的系统监控工具。我希望在我从设备接收的连续原始数据流上运行过滤器(如高斯过滤器或类似过滤器)(在这种情况下为我的cpu%)。

数据值的集合长度为n个元素。每次运行这段代码时,它会附加新的cpu值并删除最旧的,保留集合的长度为n,基本上为deque([float('nan')] * n, maxlen=n),其中n是图的长度i&# 39; m密谋。

然后它通过高斯滤波器过滤整个集合,创建平滑的数据点,然后绘制它们,创建一个类似于计算机上的大多数系统监视器cpu%图形的动画图形。

这很好用......但是每次添加新的数据val时,必须有一种更有效的方法来过滤传入的数据,而不是在整个数据集上运行过滤器(在我的情况下,图表会更新每一个.2秒)

我可以想办法在不过滤整个列表的情况下这样做,但我不确定它们是否非常有效。信号处理领域有什么东西对我有用吗?抱歉,如果我的解释有点令人困惑,我对此非常陌生。

from scipy.ndimage.filters import gaussian_filter1d

# Not my actual code but hopefully describes what im doing
def animate():  # function that is called every couple of milliseconds to animate the graph
    # ... other stuff
    values.append(get_new_val) # values = collection of data vals from cpu
    line.set_ydata(gaussian_filter1d(values, sigma=4)) # line = the line object used for graphing 
    # ... other stuff
    graph_line(line)  # function that graphs the line

tl; dr:寻找一种优化的方法来平滑原始流数据,而不是每次传递都过滤整个数据集。

1 个答案:

答案 0 :(得分:1)

我从未使用过一个,但你需要的是听起来Savitzky–Golay filter的含义。它是一个本地平滑过滤器,可用于使数据更具可微分性(并区分它,而我们也可以区分它)。

好消息是版本0.14 scipy supports this filter。文档的相关部分:

scipy.signal.savgol_filter(x, window_length, polyorder, deriv=0, delta=1.0, axis=-1, mode='interp', cval=0.0)

  Apply a Savitzky-Golay filter to an array.
  This is a 1-d filter. If x has dimension greater than 1, axis determines the axis along which the filter is applied.
  Parameters:   

  x : array_like
      The data to be filtered. If x is not a single or double precision floating point array, it will be converted to type numpy.float64 before ftering.
  window_length : int
      The length of the filter window (i.e. the number of coefficients). window_length must be a positive odd integer.
  polyorder : int
      The order of the polynomial used to fit the samples. polyorder must be less than window_length.
  [...]

我首先确定一对小多项式阶数和窗口大小。您只需要平滑大约n长度的deque,而不是使用完整的window_length数据点。当每个新数据点出现时,您必须将其附加到较小的deque,应用Savitzky-Golay过滤器,获取新的过滤点,然后将其附加到图表中。

但请注意,在我看来,当不在数据集的边缘时,该方法大多定义得很好。这可能意味着,为了精确起见,您可能需要引入一些测量值'延迟,所以你总是可以使用给定窗口内的点(我的意思是,对于给定时间点你可能需要"未来"数据点以获得可靠的过滤值)。考虑到您的数据每秒测量五次,如果有必要,这可能是一个合理的妥协。