Другой подход (больше слов, меньше кода), который может помочь:
Положения локальных максимумов и минимумов также являются местоположениями пересечений нуля первой производной. Как правило, гораздо проще найти пересечение нуля, чем непосредственно локальные максимумы и минимумы.
К сожалению, первая производная имеет тенденцию «усиливать» шум, поэтому, когда в исходных данных присутствует значительный шум, первую производную лучше всего использовать только после применения некоторой степени сглаживания к исходным данным.
Поскольку сглаживание, в простейшем смысле, является фильтром нижних частот, сглаживание часто лучше (ну, проще всего) выполняется с использованием ядра свертки, и «формирование» этого ядра может обеспечить удивительное количество возможностей сохранения / улучшения функций. , Процесс поиска оптимального ядра можно автоматизировать с помощью различных средств, но лучшим может быть простой перебор (достаточно быстро для поиска небольших ядер). Хорошее ядро (как и предполагалось) сильно исказит исходные данные, но НЕ повлияет на расположение интересующих пиков / впадин.
К счастью, довольно часто подходящее ядро можно создать с помощью простого SWAG («обоснованное предположение»). Ширина сглаживающего ядра должна быть немного шире, чем самый широкий ожидаемый «интересный» пик в исходных данных, а его форма будет напоминать этот пик (одномасштабный вейвлет). Для ядер, сохраняющих среднее значение (каким должен быть любой хороший сглаживающий фильтр), сумма элементов ядра должна быть точно равна 1,00, и ядро должно быть симметричным относительно своего центра (то есть у него будет нечетное количество элементов.
При оптимальном сглаживающем ядре (или небольшом количестве ядер, оптимизированных для различного содержания данных) степень сглаживания становится масштабным коэффициентом («усилением») ядра свертки.
Определение «правильной» (оптимальной) степени сглаживания (усиления ядра свертки) можно даже автоматизировать: сравните стандартное отклонение данных первой производной со стандартным отклонением сглаженных данных. То, как соотношение двух стандартных отклонений изменяется с изменением степени сглаживания кулачка, можно использовать для прогнозирования эффективных значений сглаживания. Все, что нужно, - это несколько ручных прогонов данных (которые действительно репрезентативны).
Все предыдущие решения, опубликованные выше, вычисляют первую производную, но они не рассматривают ее как статистическую меру, а также вышеупомянутые решения не пытаются выполнить сглаживание с сохранением / улучшением характеристик (чтобы помочь тонким пикам "перепрыгнуть" над шумом).
Наконец, плохая новость: поиск «настоящих» пиков становится головной болью, когда шум также имеет характеристики, которые выглядят как настоящие пики (перекрывающаяся полоса пропускания). Следующим более сложным решением обычно является использование более длинного ядра свертки («более широкая апертура ядра»), которое учитывает взаимосвязь между соседними «реальными» пиками (например, минимальную или максимальную частоту появления пика) или использование нескольких свертка проходит с использованием ядер, имеющих разную ширину (но только если это быстрее: фундаментальная математическая истина заключается в том, что линейные свертки, выполняемые последовательно, всегда могут быть свернуты вместе в одну свертку). Но зачастую гораздо проще сначала найти последовательность полезных ядер (разной ширины) и свести их вместе, чем напрямую найти окончательное ядро за один шаг.
Надеюсь, это предоставит достаточно информации, чтобы позволить Google (и, возможно, хорошей статистике) заполнить пробелы. Мне очень жаль, что у меня не было времени предоставить рабочий пример или ссылку на него. Если кто-нибудь встретит что-нибудь в сети, опубликуйте его здесь!