Это немного зависит от ваших определений "пика" и "впадины". Часто человек может заботиться о сглаженных пиках и впадинах для выявления широких тенденций, особенно при наличии шума. В случае, если вы хотите, чтобы каждый мелкозернистый провал или рост данных хотя (и если ваши строки отсортированы), вы можете немного обмануть с векторизованными подпрограммами от numpy
.
import numpy as np
d = np.diff(df['Return'])
i = np.argwhere((d[:-1]*d[1:])<=0).flatten()
special_points = df['Topic'][i+1]
Первая строка с np.diff()
сравнивает каждое возвращаемое значение со следующим возвращаемым значением. В частности, он их вычитает. В зависимости от вашего определения локального пика / впадины, у них будет свойство, что у вас есть только функция, которую вы ищете, если эти попарные различия чередуются по знаку. Рассмотрим следующий пик.
[1, 5, 1]
Если вы вычислите попарные разности, вы получите немного более короткий вектор
[4, -4]
Обратите внимание, что они чередуются в знаке. Следовательно, если вы умножите их, вы получите -16
, что должно быть отрицательным. Это точное понимание, которое наш код использует для определения пиков и впадин. Уменьшение размера немного смещает вещи, поэтому мы смещаем найденные индексы на 1 (в блоке df['Topic'][i+1]
).
Предостережения : Обратите внимание, что вместо строгого неравенства у нас есть <=
. Это в случае, если у нас более широкий пик, чем обычно. Рассмотрим [1, 2, 2, 2, 2, 2, 1]
. Возможно, строка 2 представляет пик и должна быть захвачена. Если это нежелательно, сделайте неравенство строгим.
Кроме того, если вас интересуют более широкие пики, этот алгоритм все еще не верен. Это достаточно быстро, но в целом он вычисляет только супернабор пиков / впадин. Рассмотрим следующее
[1, 2, 2, 3, 2, 1]
Возможно, число 3 является единственным пиком в этом наборе данных (конечно, немного зависит от ваших определений), но наш алгоритм также подберет первый и второй экземпляры числа 2, поскольку они находятся на полке ( быть идентичным соседу).
Дополнительно : Модуль scipy.signal
имеет множество алгоритмов нахождения пиков, которые могут лучше подходить в зависимости от любых дополнительных требований, предъявляемых к вашим пикам. Модификация этого решения вряд ли будет такой же быстрой или чистой, как при использовании соответствующего встроенного процессора сигналов. Звонок на scipy.signal.find_peaks()
может в основном повторить все, что мы здесь сделали, и у него есть больше вариантов, если они вам нужны. Другие алгоритмы, такие как scipy.signal.find_peaks_cwt()
, могут быть более подходящими, если вам нужен какой-либо тип сглаживания или более сложные операции.