Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

numpy sort a structured array by two fields, ascending and descending orders

I have this line of code:

TableArr = numpy.sort(TableArr, order=['destID','ATTRACT'])

I need the 'ATTRACT' order to be descending while the destID to be ascending, which is default for both. Attempts with [::-1] failed, as it reverses the entire array.

I'll add that a reverse argument that can be set to True or False was mentioned elsewhere, but it doesn't work for me and isn't mentioned in the Numpy's documentation.

like image 522
Blerg Avatar asked Oct 19 '22 03:10

Blerg


1 Answers

Here's an interactive session that tests the idea in my comment:

In [1]: import numpy as np

In [2]: dt = np.dtype([('destID',int),('ATTRACT',float),('other','S10')])
In [3]: TableArr=np.zeros((10,),dt)
In [5]: TableArr['destID']=np.random.randint(10,size=(10,))
In [6]: TableArr['ATTRACT']=np.random.randint(100,size=(10,))

In [7]: TableArr
Out[7]: 
array([(2, 39.0, b''), (7, 7.0, b''), (8, 74.0, b''), (5, 83.0, b''),
       (5, 3.0, b''), (9, 26.0, b''), (8, 9.0, b''), (3, 1.0, b''),
       (1, 67.0, b''), (7, 5.0, b'')], 
      dtype=[('destID', '<i4'), ('ATTRACT', '<f8'), ('other', 'S10')])

In [13]: Tcopy=TableArr[['destID','ATTRACT']].copy()
# use copy() to avoid a FutureWarning

In [14]: Tcopy['ATTRACT'] *= -1  # 'reverse' a field

In [16]: I=np.argsort(Tcopy,order=['destID','ATTRACT'])

In [17]: I
Out[17]: array([8, 0, 7, 3, 4, 1, 9, 2, 6, 5], dtype=int32)

In [18]: TableArr[I]
Out[18]: 
array([(1, 67.0, b''), (2, 39.0, b''), (3, 1.0, b''), (5, 83.0, b''),
       (5, 3.0, b''), (7, 7.0, b''), (7, 5.0, b''), (8, 74.0, b''),
       (8, 9.0, b''), (9, 26.0, b'')], 
      dtype=[('destID', '<i4'), ('ATTRACT', '<f8'), ('other', 'S10')])

The integers are increasing, and for the 3 cases where they tie, the floats are decreasing. So it works.

like image 176
hpaulj Avatar answered Oct 21 '22 15:10

hpaulj