Numpy 2D array indexing without out of bound and with clipping value
<p>I have indices array </p>

<pre><code>a = np.array([
   [0, 0],
   [1, 1],
   [1, 9]
])
</code></pre>

<p>And 2D array</p>

<pre><code>b = np.array([
   [0, 1, 2, 3],
   [5, 6, 7, 8]
])
</code></pre>

<p>I can do this one</p>

<pre><code>b[a[:, 0], a[:, 1]]
</code></pre>

<p>But it'll be an exception '<strong>out of bounds</strong>', because 9 is out of range. 
I need a <em>very fast way</em> to make array slice by indices and it will be ideal if I can set a clip value, e.g.:</p>

<pre><code>np.indexing_with_clipping(array=b, indices=a, clipping_value=0)
&gt; array([0, 6, --&gt; 0 = clipped value &lt;--])
</code></pre>

<p>Here's an approach -</p>

<pre><code>def indexing_with_clipping(arr, indices, clipping_value=0):
    idx = np.where(indices &lt; arr.shape,indices,clipping_value)
    return arr[idx[:, 0], idx[:, 1]]
</code></pre>

<p>Sample runs -</p>

<pre><code>In [266]: arr
Out[266]: 
array([[0, 1, 2, 3],
       [5, 6, 7, 8]])

In [267]: indices
Out[267]: 
array([[0, 0],
       [1, 1],
       [1, 9]])

In [268]: indexing_with_clipping(arr,indices,clipping_value=0)
Out[268]: array([0, 6, 5])

In [269]: indexing_with_clipping(arr,indices,clipping_value=1)
Out[269]: array([0, 6, 6])

In [270]: indexing_with_clipping(arr,indices,clipping_value=2)
Out[270]: array([0, 6, 7])

In [271]: indexing_with_clipping(arr,indices,clipping_value=3)
Out[271]: array([0, 6, 8])
</code></pre>

<hr>

<p>With focus on memory and performance efficiency, here's an approach that modifies the indices within the function -</p>

<pre><code>def indexing_with_clipping_v2(arr, indices, clipping_value=0):
    indices[indices &gt;= arr.shape] = clipping_value
    return arr[indices[:, 0], indices[:, 1]]
</code></pre>

<p>Sample run -</p>

<pre><code>In [307]: arr
Out[307]: 
array([[0, 1, 2, 3],
       [5, 6, 7, 8]])

In [308]: indices
Out[308]: 
array([[0, 0],
       [1, 1],
       [1, 9]])

In [309]: indexing_with_clipping_v2(arr,indices,clipping_value=2)
Out[309]: array([0, 6, 7])
</code></pre>

python arrays numpy multidimensional-array