Sort Python array (Numpy)

I have this array named v, dtype ('float64'):

array([[ 9.33350000e+05, 8.75886500e+06, 3.45765000e+02], [ 4.33350000e+05, 8.75886500e+06, 6.19200000e+00], [ 1.33360000e+05, 8.75886500e+06, 6.76650000e+02]]) 

... which I acquired from a file using the np.loadtxt command. I would like to sort it after the values โ€‹โ€‹of the first column without mixing the structure that holds the numbers listed on the same line together. Using v.sort (axis = 0) gives me:

 array([[ 1.33360000e+05, 8.75886500e+06, 6.19200000e+00], [ 4.33350000e+05, 8.75886500e+06, 3.45765000e+02], [ 9.33350000e+05, 8.75886500e+06, 6.76650000e+02]]) 

... i.e. puts the smallest number of the third column in the first row, etc. I would like to get something like this ...

 array([[ 1.33360000e+05, 8.75886500e+06, 6.76650000e+02], [ 4.33350000e+05, 8.75886500e+06, 6.19200000e+00], [ 9.33350000e+05, 8.75886500e+06, 3.45765000e+02]]) 

... where the elements of each row are not moved relative to each other.

+8
source share
4 answers

Try

 v[v[:,0].argsort()] 

(while v is an array). v[:,0] is the first column, and .argsort() returns the indexes that sort the first column. Then you apply this order to the entire array using advanced indexing. Note that you get a copy of the array instance.

The only way I know to sort the array in place is to use the dtype notation:

 v.dtype = [("x", float), ("y", float), ("z", float)] v.shape = v.size v.sort(order="x") 
+13
source

As an alternative

Try

 import numpy as np order = v[:, 0].argsort() sorted = np.take(v, order, 0) 

'order' has the order of the first line. and then "np.take" take the columns in the appropriate order.

See 'np.take' help for how

 help(np.take) 

take (a, indices, axis = None, out = None, Mode = "raise") Take elements from the array along the axis.

 This function does the same thing as "fancy" indexing (indexing arrays using arrays); however, it can be easier to use if you need elements along a given axis. Parameters ---------- a : array_like The source array. indices : array_like The indices of the values to extract. axis : int, optional The axis over which to select values. By default, the flattened input array is used. out : ndarray, optional If provided, the result will be placed in this array. It should be of the appropriate shape and dtype. mode : {'raise', 'wrap', 'clip'}, optional Specifies how out-of-bounds indices will behave. * 'raise' -- raise an error (default) * 'wrap' -- wrap around * 'clip' -- clip to the range 'clip' mode means that all indices that are too large are 

replace by index, which refers to the last element along this axis. Note that this disables indexing with negative numbers.

 Returns ------- subarray : ndarray The returned array has the same type as `a`. See Also -------- ndarray.take : equivalent method Examples -------- >>> a = [4, 3, 5, 7, 6, 8] >>> indices = [0, 1, 4] >>> np.take(a, indices) array([4, 3, 6]) In this example if `a` is an ndarray, "fancy" indexing can be used. >>> a = np.array(a) >>> a[indices] array([4, 3, 6]) 
+5
source

If you have instances where v[:,0] has some identical values, and you want to sort columns 1, 2, etc. again, then you will want to use numpy.lexsort() or numpy.sort(v, order=('col1', 'col2', etc..) , but for the case order= v should be a structured array.

0
source

An example numpy.lexsort() application for sorting array rows and working with relationships in the first column. Note that lexsort efficiently sorts the columns and starts from the last column, so you need to reverse the lines of a , then transpose before lexsort and finally transpose the result (you might think this should be easier, but hey!):

 In [1]: import numpy as np In [2]: a = np.array([[1,2,3,4],[1,0,4,1],[0,4,1,1]]) In [3]: a[np.lexsort(np.flip(a, axis=1).T).T] Out[3]: array([[0, 4, 1, 1], [1, 0, 4, 1], [1, 2, 3, 4]]) In [4]: a Out[4]: array([[1, 2, 3, 4], [1, 0, 4, 1], [0, 4, 1, 1]]) 

Thanks @Paul for suggesting using lexsort .

0
source

All Articles