numpy binning: how to get array indexes satisfying a predicate
<p>I have a vector <code>g</code> of values of length 1024 and a smaller vector <code>f</code> of size 32 defining bin boundaries. <code>v</code> and <code>f</code> are sorted in ascending order. I want to return an array of vectors i.e <code>[v_1,v_2,v_3,...]</code> of length <code>len(f)</code> such that each vector <code>v_i</code> contains indices of <code>g</code> between <code>f_i</code> and <code>f_i + 1</code>. Is there a NumPy way to do such a thing that does not involve looping?</p>

<p>You can use <code>searchsorted</code> to find the sorted positions of <code>f</code> in <code>g</code>.  These give the lower and upper bounds of the ranges that you want:</p>

<p>For example,</p>

<pre><code>In [42]: g
Out[42]: 
array([ 1, 11, 19, 20, 21, 32, 36, 41, 47, 53, 54, 55, 65, 66, 69, 74, 76,
       87, 89, 94])

In [43]: f
Out[43]: [0, 10, 20, 50, 100]

In [44]: binedges = g.searchsorted(f)

In [45]: binedges
Out[45]: array([ 0,  1,  3,  9, 20])
</code></pre>

<p>The array <code>binedges</code> gives you all the information that you need: the range of indices for bin <code>k</code> is <code>range(binedges[k], binedges[k+1])</code>.</p>

<p>Here's how you could create an explicit list of the indices in each bin:</p>

<pre><code>In [46]: rngs = [list(range(binedges[k], binedges[k+1])) for k in range(len(binedges)-1)]

In [47]: rngs
Out[47]: [[0], [1, 2], [3, 4, 5, 6, 7, 8], [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]]
</code></pre>

python numpy