Here's an approach -
def indexing_with_clipping(arr, indices, clipping_value=0):
idx = np.where(indices < arr.shape,indices,clipping_value)
return arr[idx[:, 0], idx[:, 1]]
Sample runs -
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])
With focus on memory and performance efficiency, here's an approach that modifies the indices within the function -
def indexing_with_clipping_v2(arr, indices, clipping_value=0):
indices[indices >= arr.shape] = clipping_value
return arr[indices[:, 0], indices[:, 1]]
Sample run -
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])