# [Numpy-discussion] Is this the optimal way to take index along a single axis?

Jonathan Taylor jonathan.taylor at utoronto.ca
Tue Mar 8 15:03:28 EST 2011

```I am wanting to use an array b to index into an array x with dimension
bigger by 1 where the element of b indicates what value to extract
along a certain direction.  For example, b = x.argmin(axis=1).
Perhaps I want to use b to create x.min(axis=1) but also to index
perhaps another array of the same size.

I had a difficult time finding a way to do this with np.take easily
and even with fancy indexing the resulting line is very complicated:

In : x.shape
Out: (2, 3, 4)

In : x.min(axis=1)
Out:
array([[ 2,  1,  7,  4],
[ 8,  0, 15, 12]])

In : x[np.arange(x.shape)[:,np.newaxis,np.newaxis],
idx[:,np.newaxis,:], np.arange(x.shape)]
Out:
array([[[ 2,  1,  7,  4]],

[[ 8,  0, 15, 12]]])

In any case I wrote myself my own function for doing this (below) and
am wondering if this is the best way to do this or if there is
something else in numpy that I should be using? -- I figure that this
is a relatively common usecase.

Thanks,
Jon.

def mytake(A, b, axis):
assert len(A.shape) == len(b.shape)+1

idx = []
for i in range(len(A.shape)):
if i == axis:
temp = b.copy()
shapey = list(temp.shape)
shapey.insert(i,1)
else:
temp = np.arange(A.shape[i])
shapey = *len(b.shape)
shapey.insert(i,A.shape[i])
shapey = tuple(shapey)
temp = temp.reshape(shapey)
idx += [temp]

return A[tuple(idx)].squeeze()

In : util.mytake(x,x.argmin(axis=1), 1)
Out:
array([[ 2,  1,  7,  4],
[ 8,  0, 15, 12]])

In : x.min(axis=1)
Out:
array([[ 2,  1,  7,  4],
[ 8,  0, 15, 12]])

```