title: Quickly Find the Index in an Array Closest to Some Value
body: <p>I have an array of values, t, that is always in increasing order (but not always uniformly spaced).  I have another single value, x.  I need to find the index in t such that t[index] is closest to x.  The function must return zero for x &lt; t.min() and the max index (or -1) for x > t.max().</p>
  
  <p>I've written two functions to do this.  The first one, f1, is MUCH quicker in this simple timing test.  But I like how the second one is just one line.  This calculation will be done on a large array, potentially many times per second.</p>
  
  <p>Can anyone come up with some other function with comparable timing to the first but with cleaner looking code?  How about something quicker then the first (speed is most important)?</p>
  
  <p>Thanks!</p>
  
  <p>Code:</p>
  
  <pre><code>import numpy as np
  import timeit
  
  t = np.arange(10,100000)         # Not always uniform, but in increasing order
  x = np.random.uniform(10,100000) # Some value to find within t
  
  def f1(t, x):
     ind = np.searchsorted(t, x)   # Get index to preserve order
     ind = min(len(t)-1, ind)      # In case x &gt; max(t)
     ind = max(1, ind)             # In case x &lt; min(t)
     if x &lt; (t[ind-1] + t[ind]) / 2.0:   # Closer to the smaller number
        ind = ind-1
     return ind
  
  def f2(t, x):
     return np.abs(t-x).argmin()
  
  print t,           '\n', x,           '\n'
  print f1(t, x),    '\n', f2(t, x),    '\n'
  print t[f1(t, x)], '\n', t[f2(t, x)], '\n'
  
  runs = 1000
  time = timeit.Timer('f1(t, x)', 'from __main__ import f1, t, x')
  print round(time.timeit(runs), 6)
  
  time = timeit.Timer('f2(t, x)', 'from __main__ import f2, t, x')
  print round(time.timeit(runs), 6)
  </code></pre>