简体   繁体   中英

Sort array based on value and create new array

Imagine a two dimensional array:

a = np.array([[1,1],[1, 0],[0, 0],[0, 0],[0, 0],[1, 1],[1, 1],[0, 1]])

I want to sort the array based on its first value like:

[[1,1],[1, 1],[1, 1],[1, 0],[0, 1],[0, 0],[0, 0],[0, 0]]

If I am simply going with a.sort() like:

a[::-1].sort(axis=0)

and the returned array looks like:

array([[1, 1],
       [1, 1],
       [1, **1**],
       [**1**, 1],
       [0, 0],
       [0, 0],
       [0, 0],
       [0, 0]])

As you can see the bold 1 used to be a zero. Why is the function flipping around my numbers? I searched the inte.net and haven't found any answers.

the sort you are doing is a sort of all columns in the array independently of each other, from the first example on this page https://numpy.org/doc/stable/reference/generated/numpy.sort.html

>>> a = np.array([[1,4],[3,1]])
>>> np.sort(a)                # sort along the last axis
array([[1, 4],
       [1, 3]])
>>> np.sort(a, axis=None)     # sort the flattened array
array([1, 1, 3, 4])
>>> np.sort(a, axis=0)        # sort along the first axis
array([[1, 1],
       [3, 4]])

also see this answer to sort the rows based on a single column: Sorting arrays in NumPy by column

The problem is that numpy sort when you pass axis=0 is sorting each column independently (see examples on doc page). If you want to sort rows, then you can use sorted instead:

np.array(sorted(a, key=lambda x: x.tolist(), reverse=True))

In your case the result is

[[1 1]
 [1 1]
 [1 1]
 [1 0]
 [0 1]
 [0 0]
 [0 0]
 [0 0]]

You can use np.lexsort , and pass the two columns independently, then reverse the order. lexsort returns the sorted indices, given the key. You need to put first column second, because the primary key in lexsort is the last column:

>>> a[np.lexsort((a[:,1], a[:,0]))][::-1]
 
array([[1, 1],
       [1, 1],
       [1, 1],
       [1, 0],
       [0, 1],
       [0, 0],
       [0, 0],
       [0, 0]])

Here is the output of np.lexsort on your data:

                 key1     key2 (primary)
>>> np.lexsort((a[:,1], a[:,0]))
 array([2, 3, 4, 7, 1, 0, 5, 6], dtype=int64)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM