0

I've got a multidimensional array of shape (1000000,3,2). Essentially it is 1 million sets of samples, each sample being 3 coordinates (each coordinate has an x and y component). I would like to sort each of the samples by the y component of each coordinate. For example, if vecCoords is the full array andI have one of the samples being vecCoords[0,:,:] = [[1,3],[2,1],[4,2]], I want it sorted to give me [[2,1],[4,2],[1,3]]. I was this vectorized so it is done for each of the 1 million samples. So, the output shape is still (1000000,3,2). I tried doing it iteratively, but my code isn't giving me the correct results there, and it is also slower than I would like.

0

1 Answer 1

1

Make a small sample array:

In [153]: arr = np.random.randint(0,100,(4,3,2))
In [154]: arr
Out[154]: 
array([[[21, 12],
        [15, 31],
        [17, 88]],

       [[35, 81],
        [99, 58],
        [39, 46]],

       [[54, 54],
        [85, 71],
        [ 9, 19]],

       [[25, 46],
        [62, 61],
        [74, 69]]])

The values you want to sort:

In [155]: arr[:,:,1]
Out[155]: 
array([[12, 31, 88],
       [81, 58, 46],
       [54, 71, 19],
       [46, 61, 69]])
In [156]: idx=np.argsort(arr[:,:,1], axis=1)
In [157]: idx
Out[157]: 
array([[0, 1, 2],
       [2, 1, 0],
       [2, 0, 1],
       [0, 1, 2]])

Test this sort on one plane:

In [159]: arr[1,idx[1],:]
Out[159]: 
array([[39, 46],
       [99, 58],
       [35, 81]])

Apply it to all planes:

In [161]: arr[np.arange(arr.shape[0])[:,None], idx,:]
Out[161]: 
array([[[21, 12],
        [15, 31],
        [17, 88]],

       [[39, 46],
        [99, 58],
        [35, 81]],

       [[ 9, 19],
        [54, 54],
        [85, 71]],

       [[25, 46],
        [62, 61],
        [74, 69]]])

While I had a general idea where I was heading with this, I still had to experiment a bit.

A newish function is supposed to make this easier - though even here I had to try a couple of things:

In [168]: np.take_along_axis(arr,idx[:,:,None], axis=1)
Out[168]: 
array([[[21, 12],
        [15, 31],
        [17, 88]],

       [[39, 46],
        [99, 58],
        [35, 81]],

       [[ 9, 19],
        [54, 54],
        [85, 71]],

       [[25, 46],
        [62, 61],
        [74, 69]]])
Sign up to request clarification or add additional context in comments.

1 Comment

Brilliant, thank you for being thorough and explaining each step!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.