【问题标题】:Multithreading 1D Median Filtering in PythonPython中的多线程一维中值滤波
【发布时间】:2020-02-19 21:17:59
【问题描述】:

我在时间序列信号上尝试了以下python中值滤波,以找到最快和更有效的函数。

sig 是一个 numpy 数组,大小为 80×188,其中包含由 80 个传感器测量的 188 个样本。

import numpy as np
from scipy.ndimage import median_filter
from scipy.signal import medfilt
from scipy.signal import medfilt2d
import time

sig = np.random.rand(80,188).astype('f')
print(type(sig))
print(type(sig[0][0]))


window_length = 181

t = time.time()
sigFiltered = medfilt2d(sig, (1,window_length))
elapsed = time.time() - t
print('scipy.signal.medfilt2d: %g seconds' % elapsed)

t = time.time()
sigFiltered = median_filter(sig, (1,window_length))
elapsed = time.time() - t
print('scipy.ndimage.median_filter: %g seconds' % elapsed)

t = time.time()
sigFiltered = medfilt(sig, (1,window_length))
elapsed = time.time() - t
print('scipy.signal.medfilt: %g seconds' % elapsed)

代码可以试试here

过滤器的结果是另一个大小为80×188 的时间序列数组,每个传感器都有平滑的时间点。

MATLAB medfilt1(sig, 181, [], 2) 对相同数据执行过滤的速度比 scipy.signal.medfilt2d 快 10 倍,这是其他函数中最快的。在我的机器上,MATLAB=2ms vs Python=20ms。我认为 MATLAB 执行多线程处理,而 python 没有。

有没有什么方法可以执行多线程中值过滤来加快处理速度并将传感器分配给不同的线程? python中是否有更有效的中值过滤?能否达到MATLAB win python的性能或者至少更接近呢?

【问题讨论】:

  • 你需要多快?
  • 小于 1 毫秒。
  • 过滤器长度应该是181?这是一个时间序列,您每 1 毫秒获得 80x185 个数据样本吗?
  • 没错。

标签: python multithreading matlab numpy median


【解决方案1】:

相对于输入的这么长的过滤器,大多数使用标准 medfilt 的输出将是相同的。如果这是一个卷积,这将是一个“完整”卷积。如果您只为“有效”卷积提供输出,那么在这种情况下会快得多:

t = time.time()
medians = []
for i in range(188-181):
    sig2 = sig[:, i:i+window_length]
    f = np.median(sig2, axis=1)
    medians.append(f)

sigFiltered = np.stack(medians).T
elapsed = time.time() - t
print('numpy.median: %g seconds' % elapsed)
numpy.median: 0.0015518 seconds

这是在每 188 个样本大小所请求的 1 毫秒运行时间的范围内。

考虑到即使是这里的每个唯一值也会随着新的输入样本而变化非常缓慢/很少。因此,您可以通过使用大于 1 的跃点来大大加快速度。

【讨论】:

  • 感谢您的回答。这是我机器上的时间:scipy.signal.medfilt2d: 0.146966 secondsscipy.ndimage.median_filter: 0.164019 secondsscipy.signal.medfilt: 0.337012 secondsnumpy.median: 0.329585 seconds。与其他功能相比,使用您提出的解决方案需要更长的时间。
  • :s 这没有意义,那应该是一个非常非常快的功能。你能尝试 100 次重复,并报告中位时间吗?可能是该过程被操作系统中断,在这种情况下,任何事情都会看起来很慢
  • 结果与您的分析一致:scipy.signal.medfilt2d: 0.023031 seconds, scipy.ndimage.median_filter: 0.0299957 seconds, scipy.signal.medfilt: 0.191031 seconds, numpy.median: 0.00196528 seconds
  • 在您的专家意见中,您认为还有提高效率的空间吗?可以在不牺牲性能的情况下进行线程化吗?
  • 多线程在这里不太可能有帮助。 Python 具有阻止多线程的 GIL,因此必须在 C/C++ 中完成。无论如何,相对于线程的启动时间,任务是相当小的。在 numpy 数组上运行的 C/C++ 中的专用中值算法可能比 numpy 中的通用算法更快。但我预计 I/O 将很快成为这个应用程序的瓶颈,输入速率为 1000 Hz。所以在优化更多之前会在堆栈中看起来更高
【解决方案2】:

我想知道为什么您使用 181 点的中值滤波器来处理 188 的数据长度?过滤器太长了,您基本上只是丢弃所有数据并用传感器输出的全局中值替换它。典型的中值滤波器长度是几个样本,具体取决于您要过滤掉的瞬态类型。

过滤器长度也解释了为什么它这么慢。在我的机器上,您的 median_filter 示例需要 46 毫秒。使用 3 个样本的更正常的过滤器大小运行需要 0.7 毫秒。

【讨论】:

    猜你喜欢
    • 2017-06-10
    • 2016-03-07
    • 2014-08-05
    • 2015-01-08
    • 1970-01-01
    • 1970-01-01
    • 2018-01-02
    • 1970-01-01
    • 2015-06-09
    相关资源
    最近更新 更多