0

I have some complicated function called dis(x), which returns a number.

I am making two lists called let's say ,,indices'' and ,,values''. So what I do is following:

for i in np.arange(0.01,4,0.01):
    values.append(dis(i))
    indices.append(i)

So i have following problem, how do i find some index j (from indices), which dis(j) (from values) is closest to some number k.

Von
  • 35
  • 1
  • 6
  • Does this answer your question? [Find nearest value in numpy array](https://stackoverflow.com/questions/2566412/find-nearest-value-in-numpy-array) – Nick May 06 '21 at 12:17

3 Answers3

0

The way you are stating it, I see two options:

  1. Brute force it (try many indices i, and then see which dis(i) ended up closest to k. Works best when dis is reasonably fast, and the possible indices are reasonably few.
  2. Learn about optimization: https://en.wikipedia.org/wiki/Optimization_problem. This is a pretty extensive field, but the python SciPy packages has many optimization functions.
exokamen
  • 36
  • 5
0

Combination of enumerate and the argmin function in numpy will do the job for you.

import numpy as np

values = []
indices = []
def dis(x):
    return 1e6*x**2

for i in np.arange(0.01,4,0.01):
    values.append(dis(i))
    indices.append(i)
target = 10000


closest_index = np.argmin([np.abs(x-target) for x in values])
print(closest_index)
HMReliable
  • 871
  • 5
  • 11
0

Using numpy

closestindice = np.argmin(np.abs(np.array(values)-k))

But it is a strange as it does not use the 'indices' list.

May be you could skip the definition of the 'indices' list and and get the values in a numpy array.

import numpy as np


def dis(i):
    return ((i-1)**2)


nprange = np.arange(0.01, 4, 0.01)
npvalues = np.array([dis(x) for x in nprange])

k = .5
closestindice = np.abs(npvalues-k).argmin()
print(closestindice, npvalues[closestindice])

Output:

28 0.5041

By the way, if 'dis' function is not monotone on the range, you could have more than one correct answers on both side of a local extremum.

hpchavaz
  • 1,368
  • 10
  • 16