I hope this can help:
COL = 0
DIM0 = 3
a[:, a[:, :, COL].argsort()][np.diag_indices(DIM0)]
Answer from YKang on Stack OverflowFirst you need a single value which you can use to sort your cards.
An easy one would be value*4 + suit:
sortval = deck[:,:,0]*4+deck[:,:,1]
sortval *= -1 # if you want largest first
Then you use np.argsort to find out which index belongs where and use it to sort your decks. It sorts along the last axis on default, which is what we want.
sortedIdx = np.argsort(sortval)
Now you can use it to sort your deck like this:
deck = deck[np.arange(len(deck))[:,np.newaxis],sortedIdx]
The np.arange... part makes sure that every second dimension index array from sortedIdx is paired with the right first dimension index.
The whole thing:
import numpy as np
deck = np.array([[[ 6., 2.],
[ 10., 1.],
[ 5., 1.],
[ 9., 2.],
[ 4., 1.],
[ 3., 2.],
[ 11., 2.]],
[[ 6., 2.],
[ 2., 2.],
[ 2., 3.],
[ 11., 1.],
[ 11., 3.],
[ 5., 3.],
[ 4., 4.]]])
sortval = deck[:,:,0]*4+deck[:,:,1]
sortval *= -1 # if you want largest first
sortedIdx = np.argsort(sortval)
deck = deck[np.arange(len(deck))[:,np.newaxis],sortedIdx]
print(deck)
Will print:
[[[ 11. 2.]
[ 10. 1.]
[ 9. 2.]
[ 6. 2.]
[ 5. 1.]
[ 4. 1.]
[ 3. 2.]]
[[ 11. 3.]
[ 11. 1.]
[ 6. 2.]
[ 5. 3.]
[ 4. 4.]
[ 2. 3.]
[ 2. 2.]]]
Are you sorting the values only to see wich one has the highest value?? Because in this case why not use np.max()?:
deck=np.array([[[ 6., 2.],
[ 10., 1.],
[ 5., 1.],
[ 9., 2.],
[ 4., 1.],
[ 3., 2.],
[ 11., 2.]],
[[ 7., 2.],
[ 8., 1.],
[ 1., 1.],
[ 9., 2.],
[ 4., 1.],
[ 3., 2.],
[ 12., 2.]]])
np.max(deck)
Out[4]: 12.0
np.max(deck[0])
Out[5]: 11.0
To sort by the second column of a:
a[a[:, 1].argsort()]
@steve's answer is actually the most elegant way of doing it.
For the "correct" way see the order keyword argument of numpy.ndarray.sort
However, you'll need to view your array as an array with fields (a structured array).
The "correct" way is quite ugly if you didn't initially define your array with fields...
As a quick example, to sort it and return a copy:
In [1]: import numpy as np
In [2]: a = np.array([[1,2,3],[4,5,6],[0,0,1]])
In [3]: np.sort(a.view('i8,i8,i8'), order=['f1'], axis=0).view(np.int)
Out[3]:
array([[0, 0, 1],
[1, 2, 3],
[4, 5, 6]])
To sort it in-place:
In [6]: a.view('i8,i8,i8').sort(order=['f1'], axis=0) #<-- returns None
In [7]: a
Out[7]:
array([[0, 0, 1],
[1, 2, 3],
[4, 5, 6]])
@Steve's really is the most elegant way to do it, as far as I know...
The only advantage to this method is that the "order" argument is a list of the fields to order the search by. For example, you can sort by the second column, then the third column, then the first column by supplying order=['f1','f2','f0'].
A way to do this is by using the list.sort method or the sorted function together with an appropriate value of the key parameter (see the documentation:howto/sorting).
The Python documentation does a great job explaining the purpose of key parameter:
"Both list.sort() and sorted() have a key parameter to specify a function to be called on each list element prior to making comparisons."
For example, let us sort the first item of your list:
first=[[10, 2], [5, 3], [4, 4]]
def by_first(element):
"""
Sort a two-dimensional list by the first element
Param: element of the list i.e [10, 2]
Return: first item of element
"""
return element[0]
So, to sort the above list we do this
sorted(first,key=by_first)
Finally, to solve the initial problem(three-dimensional list) we just have to do the above for each item of your list
list_numbers = [[[10, 2], [5, 3], [4, 4]], [[7, 6], [4, 2], [5, 8]]]
[sorted(entry, key=by_first) for entry in list_numbers]
The code below is a simple workaround to achieve the desired output.
list= [[[10,2],[5,3],[4,4]],[[7,6],[4,2],[5,8]]]
for i in range(len(list)):
list[:][:][i].sort(key=lambda x: x[:][:][0])
print(list)
Through each iteration of the for loop, the elements are sorted one list at a time.