Reputation: 43
I am trying now for days to fix this, but I just can't get anywhere with this problem.
I have a list of lists, where each list consists of values from 0 to 5:
[[ 0. 0. 4. 2. 2. 2. 2. 2. 2. 2.]
[ 0. 0. 1. 2. 3. 3. 3. 3. 3. 3.]
[ 0. 0. 2. 3. 4. 4. 1. 2. 1. 2.]
[ 0. 0. 3. 4. 5. 1. 4. 4. 5. 5.]
...
[ 0. 0. 5. 3. 3. 3. 4. 3. 4. 3.]
[ 0. 0. 3. 4. 1. 1. 1. 1. 4. 4.]
[ 0. 0. 3. 4. 1. 3. 3. 3. 3. 1.]
[ 0. 0. 1. 4. 4. 5. 3. 4. 3. 1.]]
Now I would like to sort this list starting with the very last element, then the second last etc. all the way to the beginning, to get something like:
[[ 0. 0. 3. 4. 1. 3. 3. 3. 3. 1.]
[ 0. 0. 1. 4. 4. 5. 3. 4. 3. 1.]
[ 0. 0. 5. 3. 3. 3. 3. 3. 4. 1.]
[ 0. 0. 2. 3. 4. 4. 1. 2. 1. 2.]
...
[ 0. 0. 3. 4. 1. 1. 1. 1. 4. 4.]
[ 0. 0. 3. 3. 3. 4. 4. 4. 4. 4.]
[ 0. 0. 4. 4. 3. 4. 5. 5. 1. 5.]
[ 0. 0. 3. 4. 5. 1. 4. 4. 5. 5.]]
All replies to sorting arrays/lists questions that I found online dealt with distinct columns/elements, whereas I couldn't get this range of elements to work. In the end the only solution that worked was:
array = array[np.lexsort((array[:,-9], array[:,-8], array[:,-7], array[:,-6], array[:,-5], array[:,-4], array[:,-3], array[:,-2], array[:,-1]))]
This is not only very ugly, but also not very flexible. Any attempt to replace this command with a loop or a variable failed miserably.
Any suggestions would be very much appreciated!
Upvotes: 2
Views: 192
Reputation: 221644
You can simply transpose the input array and then use np.lexsort
to get the sorting indices for a vectorized and thus pretty efficient solution, like so -
array[np.lexsort(array[:,1:].T)]
Sample run -
In [128]: # Random array of integers
...: array = np.random.randint(0,9,(5,10))
...:
...: # Original method
...: A = ((array[:,-9], array[:,-8], array[:,-7], array[:,-6], array[:,-5], \
...: array[:,-4], array[:,-3], array[:,-2], array[:,-1]))
...: out_loopy = array[np.lexsort(A)]
...:
...: # Vectorized method
...: out_vectorized = array[np.lexsort(array[:,1:].T)]
...:
In [129]: np.allclose(out_loopy,out_vectorized)
Out[129]: True
Upvotes: 2
Reputation: 2691
Use the following sorting function
def mysort(list1,list2):
i = min(len(list1),len(list2))-1 # in case unequal lines
while (i>0) and list1[i]== list2[i]:
i -= 1
return cmp(list1[i],list2[i])
Tested with (it prints the right answer)
LL = [[ 0, 0, 4, 2, 2, 2, 2, 2, 2, 2,],
[ 0, 0, 1, 2, 3, 3, 3, 3, 3, 3,],
[ 0, 0, 2, 3, 4, 4, 1, 2, 1, 2,],
[ 0, 0, 3, 4, 5, 1, 4, 4, 5, 5,],
[ 0, 0, 5, 3, 3, 3, 4, 3, 4, 3,],
[ 0, 0, 3, 4, 1, 1, 1, 1, 4, 4,],
[ 0, 0, 3, 4, 1, 3, 3, 3, 3, 1,],
[ 0, 0, 1, 4, 4, 5, 3, 4, 3, 1,]]
LL.sort(mysort)
print (LL)
Upvotes: 0
Reputation: 104062
Given:
LoL=[[ 0., 0., 4., 2., 2., 2., 2., 2., 2., 2.,],
[ 0., 0., 1., 2., 3., 3., 3., 3., 3., 3.,],
[ 0., 0., 2., 3., 4., 4., 1., 2., 1., 2.,],
[ 0., 0., 3., 4., 5., 1., 4., 4., 5., 5.,],
[ 0., 0., 5., 3., 3., 3., 4., 3., 4., 3.,],
[ 0., 0., 3., 4., 1., 1., 1., 1., 4., 4.,],
[ 0., 0., 3., 4., 1., 3., 3., 3., 3., 1.,],
[ 0., 0., 1., 4., 4., 5., 3., 4., 3., 1.,]]
Use a key function:
>>> sorted(LoL, key=lambda l: l[::-1])
[[0.0, 0.0, 3.0, 4.0, 1.0, 3.0, 3.0, 3.0, 3.0, 1.0],
[0.0, 0.0, 1.0, 4.0, 4.0, 5.0, 3.0, 4.0, 3.0, 1.0],
[0.0, 0.0, 2.0, 3.0, 4.0, 4.0, 1.0, 2.0, 1.0, 2.0],
[0.0, 0.0, 4.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0],
[0.0, 0.0, 1.0, 2.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0],
[0.0, 0.0, 5.0, 3.0, 3.0, 3.0, 4.0, 3.0, 4.0, 3.0],
[0.0, 0.0, 3.0, 4.0, 1.0, 1.0, 1.0, 1.0, 4.0, 4.0],
[0.0, 0.0, 3.0, 4.0, 5.0, 1.0, 4.0, 4.0, 5.0, 5.0]]
If those are numpy arrays, use ndarray.sort:
>>> m=np.matrix(LoL)
>>> m
array([[ 0., 0., 4., 2., 2., 2., 2., 2., 2., 2.],
[ 0., 0., 1., 2., 3., 3., 3., 3., 3., 3.],
[ 0., 0., 2., 3., 4., 4., 1., 2., 1., 2.],
[ 0., 0., 3., 4., 5., 1., 4., 4., 5., 5.],
[ 0., 0., 5., 3., 3., 3., 4., 3., 4., 3.],
[ 0., 0., 3., 4., 1., 1., 1., 1., 4., 4.],
[ 0., 0., 3., 4., 1., 3., 3., 3., 3., 1.],
[ 0., 0., 1., 4., 4., 5., 3., 4., 3., 1.]])
>>> m[m[:,-1].argsort()]
array([[ 0., 0., 3., 4., 1., 3., 3., 3., 3., 1.],
[ 0., 0., 1., 4., 4., 5., 3., 4., 3., 1.],
[ 0., 0., 4., 2., 2., 2., 2., 2., 2., 2.],
[ 0., 0., 2., 3., 4., 4., 1., 2., 1., 2.],
[ 0., 0., 1., 2., 3., 3., 3., 3., 3., 3.],
[ 0., 0., 5., 3., 3., 3., 4., 3., 4., 3.],
[ 0., 0., 3., 4., 1., 1., 1., 1., 4., 4.],
[ 0., 0., 3., 4., 5., 1., 4., 4., 5., 5.]])
Upvotes: 2