В Python Scipy есть метод find_peaks() внутри модуля scipy.signal, который возвращает все пики на основе заданных свойств пиков. Пики — это не просто пики электрического сигнала. Пиками также считаются максимумы и минимумы математической функции.
Синтаксис:
scipy.signal.find_peaks(x, height=1, prominence=4, distance=2, width=2, threshold=1, rel_height=0.5, wlen=1, )
Где параметры:
- x (последовательность): используется для приема сигнала, пики которого необходимо найти.
- height (последовательность, ndarray, число): это может быть целое число или массив, и оно используется для установки минимальной высоты для распознаваемого пика.
- prominence (последовательность, ndarray, число): Требуемое вертикальное расстояние между пиком и его соседями известно как порог, и это очень полезно в ситуации с шумными функциями, когда мы не хотим выделять пики из шума.
- distance (число): это требуемое минимальное горизонтальное расстояние(число) между близлежащими вершинами. Это может быть весьма полезно в обстоятельствах, когда известна периодичность пиков.
- width (последовательность, ndarray, число): используется для обеспечения максимальной известности.
- threshold (последовательность, ndarray, число): используется для определения ширины пика.
- wlen (int): используется для расчета пиковой значимости.
- rel_height (int): используется для расчета высоты пика.
Давайте рассмотрим пример, выполнив следующие шаги:
- Импортируйте необходимую библиотеку, используя приведенный ниже код Python.
from scipy.signal import find_peaks from scipy.misc import electrocardiogram import matplotlib.pyplot as plt %matplotlib inline
- Создайте электрокардиограмму, используя приведенный ниже код.
value = electrocardiogram()[1000:5000]
- Теперь пики, используя приведенный ниже код.
peak, _ = find_peaks(value, height=0) plt.plot(value) plt.plot(peak, value[peak], "*") plt.plot(np.zeros_like(value), "--", color="green") plt.show()
- Метод peak_prominence()
- Метод find_peaks_cwt()
- Метод peak_widths()
- Поиск вершины и долины
- Метод argrelextrema()
Метод peak_prominence()
В Python SciPy есть метод peak_prominence(), который вычисляет вертикальное расстояние между пиком и его самой нижней контурной линией по сравнению с окружающей базовой линией сигнала.
Синтаксис:
scipy.signal.peak_prominences(x, wlen=None, peaks)
Где параметры:
- x (последовательность): используется для приема сигнала, пики которого необходимо найти.
- wlen (int): используется для указания длины окна выборки.
- peaks (последовательность): индексы пиков по x.
Метод peak_prominence() возвращает выступы (каждый пик) и основания левого и правого типа ndarray.
Давайте рассмотрим пример, выполнив следующие шаги:
- Импортируйте необходимые библиотеки, используя приведенный ниже код Python.
import numpy as np import matplotlib.pyplot as plt from scipy import signal %matplotlib inline
- Сгенерируйте сигнал, используя приведенный ниже код.
array_data = np.linspace(0, 5 * np.pi, 1100) sig = np.sin(array_data) + 0.5 * np.sin(1.7 * array_data)
- Определите выступы всех пиков, используя приведенный ниже код.
sig_peaks, _ = signal.find_peaks(sig) promin = signal.peak_prominences(sig, sig_peaks)[0] promin
- Теперь вычислите и изобразите высоту контурной линии каждого пика, используя приведенный ниже код.
contur_height = sig[sig_peaks] - promin plt.plot(sig) plt.plot(sig_peaks, sig[sig_peaks], "*") plt.vlines(x=sig_peaks, ymin=contur_height, ymax=sig[sig_peaks]) plt.show()
Метод find_peaks_cwt()
В Python SciPy есть метод find_peaks_cwt(), который использует преобразование Wavelet для поиска пиков в одномерном массиве. Сигнал из N отсчетов разлагается на низкочастотные и высокочастотные полосы с помощью пары фильтров. Каждая полоса имеет двукратную заниженную выборку, по N/2 выборки в каждой.
Синтаксис:
scipy.signal.find_peaks_cwt(vector, wavelet=None, widths, max_distances=None, window_size=None, gap_thresh=None, min_snr=0, min_length=None, noise_perc=9)
Где параметры:
- vector (ndarray): найдите пики в одномерном массиве.
- wavelet (callable): он должен возвращать одномерный массив для свертки с вектором после принятия двух аргументов. Первый аргумент определяет количество точек в выходном массиве вейвлетов, а второй — масштаб вейвлета.
- widths (): для расчета матрицы CWT используйте одну ширину или одномерный массив ширин.
- max_distances (ndarray): линия хребта соединяется в каждой строке только в том случае, если относительный максимум в строке[n] находится в пределах максимальных расстояний[n] от относительного максимума в строке[n+1].
- window_size (int): Чтобы вычислить минимальный уровень шума, укажите размер окна.
- gap_thresh (float): Если относительный максимум не будет найден внутри максимальных расстояний, возникнет разрыв. Если имеется больше точки Gap_thresh без нового относительного максимума, линия гребня завершается.
- min_snr (float): Минимальное соотношение сигнал/шум.
- min_length (int): минимальная длина линии гребня должна быть приемлемой.
- Noise_perc (float): минимальный уровень шума рассчитывается с использованием процентиля точек данных, ниже которых считается шум.
Метод find_peaks_cwt() возвращает пиковые индексы.
Импортируйте необходимые библиотеки, используя приведенный ниже код Python.
from scipy.signal import find_peaks_cwt import numpy as np
Сгенерируйте элементы массива и примените функцию sin к этому массиву, используя метод np.sin(), используя приведенный ниже код.
x_data = np.arange(0, np.pi, 0.06) sin_data = np.sin(x_data)
Рассчитайте индексы пиков или пики, используя приведенный ниже код.
peak_indices = signal.find_peaks_cwt(sin_data, np.arange(2,11)) peak_indices, x_data[peak_indices], sin_data[peak_indices]
Метод peak_widths()
В Python SciPy есть метод peak_widths(), который определяет ширину пика каждого сигнала.
Синтаксис:
scipy.signal.peak_widths(x, rel_height=0.3, peaks, wlen=None, prominence_data=None)
Где параметры:
- x (последовательность): используется для приема сигнала.
- wlen (int): используется для указания длины окна выборки.
- peaks (последовательность): индексы пиков по x.
- rel_height(float): выбирает относительную высоту, на которой ширина пика выражается в процентах от его выступаемости. Ширина пика рассчитывается по самой нижней изолинии как 1,0, а половина высоты выступа рассчитывается как 0,5.
- prominence_data (tuple): при вызове с теми же параметрами x и пиками кортеж из 3 массивов соответствует результату выдающихся пиков.
Метод peak_widths() возвращает widths (выборочную ширину пика), widths_height (высоту контурных линий, используемых для расчета ширины) и right_ips, left_ips (интерполированные положения левой и правой точек соединения горизонтальной линии на каждой высоте оценки).
Давайте посмотрим на примере, выполнив следующие шаги:
- Импортируйте необходимые библиотеки, используя приведенный ниже код Python.
import numpy as np import matplotlib.pyplot as plt from scipy import signal %matplotlib inline
- Сгенерируйте сигнал, используя приведенный ниже код.
array_data = np.linspace(0, 5 * np.pi, 1100) sig = np.sin(array_data) + 0.5 * np.sin(1.7 * array_data)
- Определите ширину всех пиков, используя приведенный ниже код.
sig_peaks, _ = signal.find_peaks(sig) promin = signal.peak_prominences(sig, sig_peaks)[0] promin
- Постройте ширину сигнала, пиков и контурных линий, используя приведенный ниже код.
plt.plot(sig) plt.plot(sig_peaks, sig[sig_peaks], "*") plt.hlines(*half_peak_res[1:], color="C4") plt.hlines(*full_peak_res[1:], color="C5") plt.show()
Поиск вершины и долины
В Python SciPy нет встроенного метода для поиска пиков и спадов сигнала, здесь мы выполним эту задачу вручную, используя метод argrelextrema(), который существует в модуле scipy.signal.
Чтобы найти пики и спады потока сигнала, выполните следующие действия:
- Импортируйте необходимые библиотеки, используя приведенный ниже код Python.
import numpy as np import matplotlib import matplotlib.pyplot as plt matplotlib.use('Agg') from scipy.signal import argrelextrema %matplotlib inline
- Сгенерируйте данные, используя приведенный ниже код.
x_data = np.arange(start = 0, stop = 30, step = 1, dtype='int') y_data = np.random.random(30)*5
- Вычислите пики, используя приведенный ниже код.
peaks_ind = argrelextrema(y_data, np.greater) peaks_ind = peaks_ind[0]
- Вычислите долины, используя приведенный ниже код.
valleys_ind = argrelextrema(y_data, np.less) valleys_ind = valleys_ind[0]
- Постройте график с данными пиков и впадин, которые мы сгенерировали с помощью приведенного ниже кода.
(fig, ax) = plt.subplots() ax.plot(x_data, y_data) x_peak = peaks_ind y_peak = y_data[peaks_ind] ax.plot(x_peak, y_peak, marker='*', linestyle='dashed', color='orange', label="peaks") x_valley = valleys_ind y_valley = y_data[valleys_ind] ax.plot(x_valley, y_valley, marker='*', linestyle='dashed', color='blue', label="Valleys")
Метод argrelextrema()
В этом разделе, мы собираемся найти минимумы или впадины данного сигнала с помощью метода argrelextrema().
Чтобы найти минимумы сигнала или заданных данных, выполните следующие действия:
- Импортируйте необходимые библиотеки, используя приведенный ниже код Python.
import numpy as np import matplotlib import matplotlib.pyplot as plt matplotlib.use('Agg') from scipy.signal import argrelextrema
- Создайте сигнал, используя случайные данные, следуя приведенному ниже коду.
array_data = np.arange(start = 0, stop = 40, step = 1, dtype='int') y_array_data = np.random.random(40)*5
- Рассчитайте минимумы сигнала, используя приведенный ниже код.
minima_ind = argrelextrema(y_array_data, np.less) minima_ind = minima_ind[0] minima_ind
- Поместите рассчитанные минимумы на график, используя приведенный ниже код.
(fig, ax) = plt.subplots() ax.plot(array_data, y_array_data) x_minima = minima_ind y_minima = y_array_data[minima_ind] ax.plot(x_minima, y_minima, marker='*', linestyle='dashed', color='green', label="Minima")