the argmin is actually calculating the values correctly. But you misunderstand what np.unravel_index is expecting.
From docs:
Converts a flat index or array of flat indices into a tuple of
coordinate arrays.
To see what kind of input it would accept to give the desired output here, We need to focus on the main point: it will convert a flat array into the correct coordinate array for a particular location in non-flat terms. Essentially, what it expected is coordinates of your desired points as if your input array was flattened.
import numpy as np
inp = np.array([[[ 0.64, 0.49, 2.56],
[ 7.84, 13.69, 21.16]],
[[ 33.64, 44.89, 57.76],
[ 77.44, 94.09, 112.36]]])
idx = inp.argmin(axis=-1)
#Output:
array([[1, 0],
[0, 0]], dtype=int64)
Note that you cannot send this idx directly because it is not representing correct coordinates for a flattened version of inp array.
That would look more like the following:
flat_idx = np.arange(0, idx.size*inp.shape[-1], inp.shape[-1]) + idx.flatten()
#Output:
array([1, 3, 6, 9], dtype=int64)
And we can see unravel_index accepts it happily.
temp = np.unravel_index(flat_idx, inp.shape)
#Output:
(array([0, 0, 1, 1], dtype=int64),
array([0, 1, 0, 1], dtype=int64),
array([1, 0, 0, 0], dtype=int64))
inp[temp]
Output:
array([ 0.49, 7.84, 33.64, 77.44])
Also, taking a look at the output tuple, we can notice that it is not too difficult to recreate the same ourselves as well. Notice that the last array corresponds to a flattened form of idx, while the first two arrays essentially enable indexing through the first two axes of inp.
And to prepare that, we can actually use the unravel_index function in a rather nifty way, as follows:
real_idx = (*np.unravel_index(np.arange(idx.size), idx.shape), idx.flatten())
inp[real_idx]
#Output:
array([ 0.49, 7.84, 33.64, 77.44])