Нахождение местного экстрима не работает должным образом в Scipy - PullRequest
2 голосов
/ 28 июня 2019

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

# Get the data
x = np.arange(start=0,
              stop=20,
              step=0.2)
y = np.cos(x)

# Calculate the gradient
gradient = []
for y1, y2 in zip(y, y[1:]):
    # Append the gradient (Delta Y / Delta X) where Delta X = 1
    gradient.append(y2-y1)

# Turn the gradient from a list to an array
gradient = np.array(gradient)

# Calculate the maximum points of the gradient
maxima = argrelextrema(gradient, np.greater_equal, order=2)
minima = argrelextrema(gradient, np.less_equal, order=2)

# Plot the original signal
plt.plot(x, y, label="Original Signal")
plt.scatter(x[maxima], y[maxima], color="red", label="Maxima")
plt.scatter(x[minima], y[minima], color="blue", label="Minima")
plt.title("Original Graph")
plt.legend(loc='lower left')
plt.show()

# Plot the gradient
plt.plot(gradient, label="First Derivative")
plt.scatter(maxima, gradient[maxima], color="red", label="Maxima")
plt.scatter(minima, gradient[minima], color="blue", label="Minima")
plt.title("1st Derivative Graph")
plt.legend(loc='lower left')
plt.show()

Это дает следующие результаты:

Local Minima and Maxima of a Cos graph

Кажется, все хорошо. Однако, когда я изменяю код так, что:

x = [my data of 720 points]
y = [my data of 720 points some are np.inf]

Ссылка на данные (сохраняется в виде файла .txt)

Я получаю очень странные результаты, как показано ниже:

Weird Minima and Maxima

Сначала я подумал, что это может быть связано с параметром order=2 функции argrelextrema или шумом в моем сигнале. Изменение order на больший размер окна уменьшает количество найденных точек, также как и включение цифрового фильтра. Я, однако, все еще не могу понять, почему он не находит максимумы и минимумы на пиках градиента, а не просто вдоль плоской области?

Примечание: Этот вопрос был обратным моей проблеме.

Edit:

Изменение параметров less_equal на less и greater_equal на greater также удаляет многие точки вдоль плоской области. Хотя я все еще не понимаю, почему максимумы и минимумы градиента не выбраны.

1 Ответ

0 голосов
/ 18 июля 2019

Проблема была исправлена!

Первая проблема заключалась в том, что данные были шумными.Это означает, что минимумы и максимумы были найдены по всей линии.Вы можете решить это двумя способами.Во-первых, вы можете применить фильтр для сглаживания линии:

from scipy import ndimage

# Filter the signal (to remove excess noise)
scanner_readings = ndimage.gaussian_filter(data, sigma=3)

Другой вариант - увеличить размер окна функций argrelextrema и argrelextrema.

# Calculate the maximum points of the gradient
maxima = argrelextrema(gradient, np.greater_equal, order=4)
minima = argrelextrema(gradient, np.less_equal, order=4)

Наконецкажется, что функции argrelextrema и argrelextrema плохо обрабатывают разрывы.Чтобы исправить это, я заменил все значения inf на максимальное найденное значение, которое в данном случае было 10. Вы можете увидеть, как я сделал это ниже:

# Remove discontinuity (10 is the max value in the data)
data[data == np.inf] = 10

Когда вы сделаете это, вы получите следующеерезультаты:

Original Signal First derivative

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