Многопоточность 1D Median Filtering в Python - PullRequest
0 голосов
/ 20 февраля 2020

Я попробовал следующую python медианную фильтрацию сигналов временных рядов , чтобы найти самую быструю и эффективную функцию.

sig - это массив размером numpy 80×188, который содержит 188 образцов, измеренных 80 датчиками.

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)

Код можно попробовать здесь .

Результатом фильтра является другой массив временных рядов размером 80×188 с сглаженными временными точками для каждого датчика.

MATLAB medfilt1(sig, 181, [], 2) выполняет фильтрацию тех же данных в 10 раз быстрее по сравнению с scipy.signal.medfilt2d, который был самым быстрым среди других функций. На моей машине MATLAB = 2 мс против Python = 20 мс. Я думаю, что MATLAB выполняет многопоточную обработку, а python - нет.

Есть ли способ выполнить многопоточную медианную фильтрацию, чтобы ускорить процесс и назначить датчики различным потокам? Существует ли более эффективная медианная фильтрация в python? Могу ли я достичь производительности MATLAB win python или хотя бы приблизиться к ней?

Ответы [ 2 ]

1 голос
/ 13 апреля 2020

При таком длинном фильтре относительно входных данных большинство выходов, использующих стандартную медпрофильство, будут одинаковыми. Где это будет свертка, это будет "полная" свертка. Если вместо этого вы дадите только выходные данные для «действительной» свертки, то в этом случае это будет намного быстрее:

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

Это значение соответствует запрошенному времени выполнения 1 мс на размер выборки 188 *. 1005 *

Учитывая, что даже каждое уникальное значение здесь будет меняться очень медленно / редко с новыми входными выборками. Поэтому вы могли бы значительно ускорить это, используя скачок больше 1.

0 голосов
/ 20 февраля 2020

Мне интересно, почему вы используете медианный фильтр 181 балл для длины данных 188? Фильтр настолько длинный, что вы просто отбрасываете все данные и заменяете их глобальной медианой выходного сигнала датчика. Типичная средняя длина фильтра может составлять несколько выборок, в зависимости от того, какой тип переходных процессов вы хотите отфильтровать.

Длина фильтра также объясняет, почему он такой медленный. На моей машине ваш median_filter пример занимает 46 мс. Работа с более нормальным размером фильтра из 3 выборок занимает 0,7 мс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...