J'ai deux tableaux x
et y
comme:
x = np.array([6, 3, 5, 2, 1, 4, 9, 7, 8])
y = np.array([2, 1, 3, 5, 3, 9, 8, 10, 7])
Je trouve l'index des minima et maxima locaux comme suit:
sortId = np.argsort(x)
x = x[sortId]
y = y[sortId]
minm = np.array([])
maxm = np.array([])
while i < y.size-1:
while(y[i+1] >= y[i]):
i = i + 1
maxm = np.insert(maxm, 0, i)
i++
while(y[i+1] <= y[i]):
i = i + 1
minm = np.insert(minm, 0, i)
i++
Quel est le problème dans ce code? La réponse devrait être l’index de minima = [2, 5, 7]
Et celle de maxima = [1, 3, 6]
.
Vous n'avez pas du tout besoin de cette boucle while
. Le code ci-dessous vous donnera la sortie que vous voulez; il trouve tous les minima locaux et tous les maxima locaux et les stocke dans minm
et maxm
, respectivement. Remarque: lorsque vous appliquez cette option à de grands ensembles de données, veillez à lisser les signaux en premier. sinon, vous allez vous retrouver avec des tonnes d'extrema.
import numpy as np
from scipy.signal import argrelextrema
import matplotlib.pyplot as plt
x = np.array([6, 3, 5, 2, 1, 4, 9, 7, 8])
y = np.array([2, 1, 3 ,5 ,3 ,9 ,8, 10, 7])
# sort the data in x and rearrange y accordingly
sortId = np.argsort(x)
x = x[sortId]
y = y[sortId]
# this way the x-axis corresponds to the index of x
plt.plot(x-1, y)
plt.show()
maxm = argrelextrema(y, np.greater) # (array([1, 3, 6]),)
minm = argrelextrema(y, np.less) # (array([2, 5, 7]),)
Cela devrait être beaucoup plus efficace que la boucle while
ci-dessus.
L'intrigue ressemble à ceci; J'ai décalé les valeurs x pour qu'elles correspondent aux indices retournés dans minm
et maxm
):
A partir de SciPy version 1.1, vous pouvez également utiliser find_peaks :
from scipy.signal import find_peaks
peaks, _ = find_peaks(y)
# this way the x-axis corresponds to the index of x
plt.plot(x-1, y)
plt.plot(peaks, y[peaks], "x")
plt.show()
Cela donne
Ce qui est bien, c’est que vous pouvez désormais aussi facilement définir une hauteur de pic minimale (par exemple 8):
peaks, _ = find_peaks(y, height=8)
# this way the x-axis corresponds to the index of x
plt.plot(x-1, y)
plt.plot(peaks, y[peaks], "x")
plt.show()
Notez que le premier pic est maintenant exclu car sa hauteur est inférieure à 8.
En outre, vous pouvez également définir la distance minimale entre les pics (par exemple 5):
peaks, _ = find_peaks(y, distance=5)
# this way the x-axis corresponds to the index of x
plt.plot(x-1, y)
plt.plot(peaks, y[peaks], "x")
plt.show()
Maintenant, le sommet moyen est exclu car sa distance aux deux autres sommets est inférieure à 5.
x=np.array([6,3,5,2,1,4,9,7,8])
y=np.array([2,1,3,5,7,9,8,10,7])
sort_idx = np.argsort(x)
y=y[sort_idx]
x=x[sort_idx]
minm=np.array([],dtype=int)
maxm=np.array([],dtype=int)
length = y.size
i=0
while i < length-1:
if i < length - 1:
while i < length-1 and y[i+1] >= y[i]:
i+=1
if i != 0 and i < length-1:
maxm = np.append(maxm,i)
i+=1
if i < length - 1:
while i < length-1 and y[i+1] <= y[i]:
i+=1
if i < length-1:
minm = np.append(minm,i)
i+=1
print minm
print maxm
minm
et maxm
contiennent des indices de minima et de maxima, respectivement.
Cela fonctionnera bien.
Python utilise +=
au lieu de ++
.
Avant d’utiliser i
dans une boucle while, vous devez attribuer une valeur - dans le cas présent 0 -, en l’initialisant pour éviter les erreurs.
import numpy as np
x=np.array([6,3,5,2,1,4,9,7,8])
y=np.array([2,1,3,5,3,9,8,10,7])
sortId=np.argsort(x)
x=x[sortId]
y=y[sortId]
minm = np.array([])
maxm = np.array([])
i = 0
while i < y.size-1:
while(y[i+1] >= y[i]):
i+=1
maxm=np.insert(maxm,0,i)
i+=1
while(y[i+1] <= y[i]):
i+=1
minm=np.insert(minm,0,i)
i+=1
print minm, maxm