Otro enfoque (más palabras, menos código) que puede ayudar:
Las ubicaciones de los máximos y mínimos locales también son las ubicaciones de los cruces por cero de la primera derivada. En general, es mucho más fácil encontrar cruces por cero que encontrar directamente máximos y mínimos locales.
Desafortunadamente, la primera derivada tiende a "amplificar" el ruido, por lo que cuando hay ruido significativo en los datos originales, es mejor usar la primera derivada solo después de que se haya aplicado algún grado de suavizado a los datos originales.
Dado que el suavizado es, en el sentido más simple, un filtro de paso bajo, el suavizado a menudo se realiza mejor (bueno, más fácilmente) mediante el uso de un kernel de convolución, y "modelar" ese kernel puede proporcionar una sorprendente cantidad de capacidad de preservación / mejora de características . El proceso de encontrar un kernel óptimo se puede automatizar usando una variedad de medios, pero lo mejor puede ser la simple fuerza bruta (bastante rápido para encontrar kernels pequeños). Un buen kernel distorsionará (según lo previsto) masivamente los datos originales, pero NO afectará la ubicación de los picos / valles de interés.
Afortunadamente, con bastante frecuencia se puede crear un kernel adecuado mediante un simple SWAG ("conjetura fundamentada"). El ancho del núcleo de suavizado debe ser un poco más ancho que el pico "interesante" esperado más ancho en los datos originales, y su forma se parecerá a ese pico (una ondícula de una sola escala). Para los núcleos que preservan la media (lo que debería ser cualquier buen filtro de suavizado), la suma de los elementos del núcleo debe ser exactamente igual a 1,00, y el núcleo debe ser simétrico con respecto a su centro (lo que significa que tendrá un número impar de elementos.
Dado un kernel de suavizado óptimo (o un pequeño número de kernels optimizados para diferentes contenidos de datos), el grado de suavizado se convierte en un factor de escala para (la "ganancia") del kernel de convolución.
La determinación del grado "correcto" (óptimo) de suavizado (ganancia del núcleo de convolución) se puede incluso automatizar: Compare la desviación estándar de los datos de la primera derivada con la desviación estándar de los datos suavizados. Cómo se usa la relación de las dos desviaciones estándar con los cambios en el grado de suavizado para predecir valores de suavizado efectivos. Unas pocas ejecuciones de datos manuales (que sean verdaderamente representativas) deberían ser todo lo que se necesita.
Todas las soluciones anteriores publicadas anteriormente calculan la primera derivada, pero no la tratan como una medida estadística, ni las soluciones anteriores intentan realizar el suavizado de preservación / mejora de características (para ayudar a que los picos sutiles "salten por encima" del ruido).
Finalmente, las malas noticias: encontrar picos "reales" se convierte en un dolor real cuando el ruido también tiene características que parecen picos reales (ancho de banda superpuesto). La siguiente solución más compleja es generalmente usar un núcleo de convolución más largo (una "apertura de núcleo más amplia") que tenga en cuenta la relación entre picos "reales" adyacentes (como tasas mínimas o máximas para la ocurrencia de picos), o usar múltiples la convolución pasa utilizando núcleos que tienen diferentes anchos (pero solo si es más rápido: es una verdad matemática fundamental que las convoluciones lineales realizadas en secuencia siempre se pueden convolucionar juntas en una sola convolución). Pero a menudo es mucho más fácil encontrar primero una secuencia de kernels útiles (de diferentes anchos) y convertirlos juntos que encontrar directamente el kernel final en un solo paso.
Con suerte, esto proporciona suficiente información para permitir que Google (y quizás un buen texto de estadísticas) llene los vacíos. Realmente desearía tener el tiempo para proporcionar un ejemplo trabajado o un enlace a uno. Si alguien encuentra uno en línea, ¡publíquelo aquí!