Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Index n dimensional array with (n-1) d array

Tags:

python

numpy

What is the most elegant way to access an n dimensional array with an (n-1) dimensional array along a given dimension as in the dummy example

a = np.random.random_sample((3,4,4))
b = np.random.random_sample((3,4,4))
idx = np.argmax(a, axis=0)

How can I access now with idx a to get the maxima in a as if I had used a.max(axis=0)? or how to retrieve the values specified by idx in b?

I thought about using np.meshgrid but I think it is an overkill. Note that the dimension axis can be any usefull axis (0,1,2) and is not known in advance. Is there an elegant way to do this?

like image 543
2006pmach Avatar asked Sep 07 '17 18:09

2006pmach


People also ask

Can you index an NP array?

Array indexing is the same as accessing an array element. You can access an array element by referring to its index number. The indexes in NumPy arrays start with 0, meaning that the first element has index 0, and the second has index 1 etc.

Can multi dimensional arrays be indexed?

Indexing multi-dimensional arraysMulti-dimensional arrays are indexed in GAUSS the same way that matrices are indexed, using square brackets [] . Scanning above, you can see that the value of the element at the intersection of the third row and second column of x1 is 8.

What is the index of the first element in a one dimensional array?

The first index in an array is not 1, but is instead 0. So, if you had an array with 3 elements in it then the elements would have indices 0, 1, and 2. More generally, if there is an array with n elements in it the indices will range from 0 to n-1. This is a key bit of information to remember.


1 Answers

Make use of advanced-indexing -

m,n = a.shape[1:]
I,J = np.ogrid[:m,:n]
a_max_values = a[idx, I, J]
b_max_values = b[idx, I, J]

For the general case:

def argmax_to_max(arr, argmax, axis):
    """argmax_to_max(arr, arr.argmax(axis), axis) == arr.max(axis)"""
    new_shape = list(arr.shape)
    del new_shape[axis]

    grid = np.ogrid[tuple(map(slice, new_shape))]
    grid.insert(axis, argmax)

    return arr[tuple(grid)]

Quite a bit more awkward than such a natural operation should be, unfortunately.

For indexing a n dim array with a (n-1) dim array, we could simplify it a bit to give us the grid of indices for all axes, like so -

def all_idx(idx, axis):
    grid = np.ogrid[tuple(map(slice, idx.shape))]
    grid.insert(axis, idx)
    return tuple(grid)

Hence, use it to index into input arrays -

axis = 0
a_max_values = a[all_idx(idx, axis=axis)]
b_max_values = b[all_idx(idx, axis=axis)]
like image 186
Divakar Avatar answered Oct 25 '22 17:10

Divakar