Une autre approche (plus de mots, moins de code) qui pourrait vous aider :
Les emplacements des maxima et minima locaux sont également les emplacements des passages par zéro de la dérivée première. Il est généralement beaucoup plus facile de trouver les passages par zéro que de trouver directement les maxima et minima locaux.
Malheureusement, la dérivée première a tendance à "amplifier" le bruit. Par conséquent, lorsqu'un bruit important est présent dans les données d'origine, il est préférable d'utiliser la dérivée première uniquement après avoir appliqué un certain degré de lissage aux données d'origine.
Puisque le lissage est, au sens le plus simple, un filtre passe-bas, le lissage est souvent mieux (enfin, plus facilement) réalisé en utilisant un noyau de convolution, et la "mise en forme" de ce noyau peut fournir une quantité surprenante de capacité de préservation/amélioration des caractéristiques. Le processus de recherche d'un noyau optimal peut être automatisé par divers moyens, mais le mieux est peut-être la simple force brute (très rapide pour trouver de petits noyaux). Un bon noyau va (comme prévu) déformer massivement les données d'origine, mais il n'affectera PAS l'emplacement des pics et des vallées d'intérêt.
Heureusement, il est souvent possible de créer un noyau approprié par le biais d'un simple SWAG ("educated guess"). La largeur du noyau de lissage doit être un peu plus large que le pic "intéressant" le plus large attendu dans les données d'origine, et sa forme doit ressembler à ce pic (une ondelette à échelle unique). Pour les noyaux préservant la moyenne (ce que devrait être tout bon filtre de lissage), la somme des éléments du noyau devrait être précisément égale à 1,00 et le noyau devrait être symétrique par rapport à son centre (ce qui signifie qu'il aura un nombre impair d'éléments.
Étant donné un noyau de lissage optimal (ou un petit nombre de noyaux optimisés pour différents contenus de données), le degré de lissage devient un facteur d'échelle pour (le "gain" du) noyau de convolution.
La détermination du degré "correct" (optimal) de lissage (gain du noyau de convolution) peut même être automatisée : Comparer l'écart type des données de la dérivée première avec l'écart type des données lissées. La façon dont le rapport entre les deux écarts types change en fonction du degré de lissage peut être utilisé pour prédire les valeurs de lissage efficaces. Quelques exécutions manuelles de données (qui sont vraiment représentatives) devraient suffire.
Toutes les solutions précédentes affichées ci-dessus calculent la dérivée première, mais elles ne la traitent pas comme une mesure statistique, et ne tentent pas non plus d'effectuer un lissage de préservation/amélioration des caractéristiques (pour aider les pics subtils à "sauter" au-dessus du bruit).
Enfin, la mauvaise nouvelle : Trouver les "vrais" pics devient un véritable casse-tête lorsque le bruit présente également des caractéristiques qui ressemblent à de vrais pics (chevauchement de la bande passante). La solution suivante, plus complexe, consiste généralement à utiliser un noyau de convolution plus long (une "ouverture de noyau plus large") qui tient compte de la relation entre les "vrais" pics adjacents (comme les taux minimum ou maximum d'apparition des pics), ou à utiliser plusieurs passes de convolution en utilisant des noyaux de largeur différente (mais seulement si c'est plus rapide : c'est une vérité mathématique fondamentale que les convolutions linéaires effectuées en séquence peuvent toujours être convoluées ensemble en une seule convolution). Mais il est souvent beaucoup plus facile de trouver d'abord une séquence de noyaux utiles (de largeurs différentes) et de les convoluer ensemble que de trouver directement le noyau final en une seule étape.
J'espère que ces informations sont suffisantes pour permettre à Google (et peut-être à un bon texte de statistiques) de combler les lacunes. J'aimerais vraiment avoir le temps de fournir un exemple concret, ou un lien vers un tel exemple. Si quelqu'un en trouve un en ligne, merci de le poster ici !
1 votes
Probablement un duplicata de Comment trouver efficacement les minima locaux d'un tableau multidimensionnel lisse dans NumPy ? .
2 votes
Non, c'est en 2D (je parle de 1D) et cela implique des fonctions personnalisées. J'ai ma propre implémentation simple, mais je me demandais s'il en existait une meilleure, fournie avec les modules Numpy/Scipy.
0 votes
Vous pourriez peut-être mettre à jour la question en précisant que (1) vous avez un tableau 1d et (2) quel type de minimum local vous recherchez. Juste une entrée plus petite que les deux entrées adjacentes ?
1 votes
Vous pouvez regarder scipy.signal.find_peaks_cwt si vous parlez de données avec du bruit.