J'ai trouvé ce post: Python: trouver un élément dans un tableau
et il s'agit de renvoyer l'index d'un tableau en faisant correspondre les valeurs.
D'autre part, ce que je pense faire est similaire mais différent. Je voudrais trouver la valeur la plus proche pour la valeur cible. Par exemple, je cherche 4.2 mais je sais que dans le tableau il n’existe pas de 4.2 mais je veux renvoyer l’indice de la valeur 4.1 au lieu de 4.4.
Quel serait le moyen le plus rapide de le faire?
Je pense le faire à l'ancienne, comme je le faisais auparavant avec Matlab, qui utilise le tableau A où je veux obtenir l'index de moins la valeur cible et en prendre l'absolu, puis sélectionner le minimum. Quelque chose comme ça:-
[~,idx] = min(abs(A - target))
C'est du code Matlab mais je suis débutant en Python, donc je me demande s'il existe un moyen rapide de le faire en Python?
Je vous remercie beaucoup pour votre aide!
Ceci est similaire à l'utilisation de bisect_left, mais cela vous permettra de passer dans un tableau de cibles
def find_closest(A, target):
#A must be sorted
idx = A.searchsorted(target)
idx = np.clip(idx, 1, len(A)-1)
left = A[idx-1]
right = A[idx]
idx -= target - left < right - target
return idx
Quelques explications:
D'abord le cas général: idx = A.searchsorted(target)
renvoie un index pour chaque target
tel que target
soit compris entre A[index - 1]
et A[index]
. J'appelle ces left
et right
afin que nous sachions que left < target <= right
. target - left < right - target
est True
(ou 1) lorsque la cible est plus proche de left
et False
(ou 0) lorsque la cible est plus proche de right
.
Maintenant, le cas spécial: quand target
est inférieur à tous les éléments de A
, idx = 0
. idx = np.clip(idx, 1, len(A)-1)
remplace toutes les valeurs de idx
<1 par 1, donc idx=1
. Dans ce cas, left = A[0]
, right = A[1]
et nous savons que target <= left <= right
. Nous savons donc que target - left <= 0
et right - target >= 0
donc target - left < right - target
est True
à moins que target == left == right
et idx - True = 0
.
Il existe un autre cas particulier si target
est supérieur à tous les éléments de A
. Dans ce cas, idx = A.searchsorted(target)
et np.clip(idx, 1, len(A)-1)
remplacent len(A)
par len(A) - 1
afin que idx=len(A) -1
et target - left < right - target
aboutissent à False
alors idx renvoie len(A) -1
. Je vous laisserai travailler à votre guise.
Par exemple:
In [163]: A = np.arange(0, 20.)
In [164]: target = np.array([-2, 100., 2., 2.4, 2.5, 2.6])
In [165]: find_closest(A, target)
Out[165]: array([ 0, 19, 2, 2, 3, 3])
Le code Numpy correspondant est presque identique, sauf que vous utilisez numpy.argmin
pour trouver l'index minimum.
idx = numpy.argmin(numpy.abs(A - target))
Eh bien, plus de 2 ans se sont écoulés et j'ai trouvé une implémentation très simple à partir de cette URL: Trouver la valeur la plus proche dans un tableau numpy
La mise en œuvre est:
def getnearpos(array,value):
idx = (np.abs(array-value)).argmin()
return idx
À votre santé!!
Testé et chronométré deux solutions:
idx = np.searchsorted(sw, sCut)
et
idx = np.argmin(np.abs(sw - sCut))
pour le calcul dans une méthode coûteuse en temps. le timing était de 113s pour le calcul avec la deuxième solution , et 132s pour le calcul avec la première .
Solution possible:
>>> a = [1.0, 3.2, -2.5, -3.1]
>>> i = -1.5
>>> diff = [(abs(i - x),idx) for (idx,x) in enumerate(a)]
>>> diff
[(2.5, 0), (4.7, 1), (1.0, 2), (1.6, 3)]
>>> diff.sort()
>>> diff
[(1.0, 2), (1.6, 3), (2.5, 0), (4.7, 1)]
Vous aurez l'indice de la valeur la plus proche en diff [0] [1]
def Finder(myList, target)
diff = ''
index = None
for i,num in enumerate(myList):
if abs(target - num) < diff:
diff = abs(target - num)
index = i
return index
J'espère que cela t'aides
MODIFIER:
Si vous souhaitez un one-liner, alors vous préférerez peut-être ceci:
min(L, key=lambda x: abs(target-x))