Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting a record array in numpy

I have an numpy structure array

import numpy as np
np.array([(0, 1, 1167606000), (0, 1, 1167606005), (0, 1, 1167606008),
       (0, 10, 1167606010), (0, 10, 1167606012), (1, 0, 1167606000),
       (1, 2, 1167606001), (1, 0, 1167606005), (1, 0, 1167606008),
       (2, 1, 1167606001), (2, 3, 1167606002), (3, 2, 1167606002),
       (3, 4, 1167606003), (4, 3, 1167606003), (4, 5, 1167606004),
       (5, 4, 1167606004), (5, 6, 1167606005), (6, 5, 1167606005),
       (6, 7, 1167606006), (7, 6, 1167606006), (7, 8, 1167606007),
       (8, 7, 1167606007), (8, 9, 1167606008), (9, 8, 1167606008),
       (9, 10, 1167606009), (10, 9, 1167606009), (10, 0, 1167606010),
       (10, 0, 1167606012)], 
      dtype=[('fr', '<i8'), ('to', '<i8'), ('time', '<i8')])

Is there a vectorized way to sort it first by the minimum of 'fr', 'to' and then by 'time'. Another thing is that I want to sort this without making any copies.

Edit: The sort is not by 'fr', 'to' and 'time', but first by the minimum of 'fr' and 'to' followed by 'time'. The expected answer in the above case is

(0, 1, 1167606000),
(1, 0, 1167606000),
(0, 1, 1167606005),
(1, 0, 1167606005), 
(0, 1, 1167606008),
(1, 0, 1167606008),
(0, 10, 1167606010), 
(0, 10, 1167606012), 
(1, 2, 1167606001), 
(2, 1, 1167606001), 
(2, 3, 1167606002), 
(3, 2, 1167606002),
(3, 4, 1167606003), 
(4, 3, 1167606003), 

...
like image 309
imsc Avatar asked Apr 30 '26 00:04

imsc


1 Answers

You can give an order argument to sort:

a.sort(order=['fr', 'to', 'time'])

Sorting by minimum of two columns:

Using lexsort, you can sort by any set of keys. Here, give it a['time'] and np.minimum(a['to'], a['fr']) (sorts by last item first)

inds = np.lexsort((a['time'], np.minimum(a['to'], a['fr'])))
a = a[inds]

To avoid making a copy of a when you rearrange it, you can use take instead of a = a[inds]

np.take(a, inds, out=a)
like image 167
askewchan Avatar answered May 01 '26 15:05

askewchan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!