【问题标题】:What is the most efficient way to filter (smooth) continuous streaming data过滤(平滑)连续流数据的最有效方法是什么
【发布时间】:2017-09-11 22:11:49
【问题描述】:

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

数据值的集合长度为n 个元素。每次运行这段代码时,它都会附加新的 cpu 值并删除最旧的保持集合的长度为 n 基本上是 deque([float('nan')] * n, maxlen=n) 其中n 是我正在绘制的图形的长度。

然后它通过高斯滤波器过滤整个集合,创建平滑的数据点,然后绘制它们,创建一个动画图表,类似于您计算机上的大多数系统监视器 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:寻找一种优化的方式来平滑原始流数据,而不是每次都过滤整个数据集。

【问题讨论】:

    标签: python scipy signal-processing smoothing


    【解决方案1】:

    我从来没有使用过,但你需要的听起来像是Savitzky–Golay filter 的用途。它是一个局部平滑过滤器,可用于使数据更具可区分性(并在我们处理数据时对其进行区分)。

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

    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 数据点,您只需平滑一个长度大约为window_length 的小得多的deque。随着每个新数据点的出现,您必须将其附加到较小的 deque,应用 Savitzky–Golay 过滤器,获取新的过滤点,并将其附加到您的图表中。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-17
      • 2015-02-27
      相关资源
      最近更新 更多