Sorting a list of arrays and one value in pandas

Question:

I’m trying to sort a list which is set up like list=([set of coordinates], euclidean distance of route between those coordinates. I want to sort the list by the shortest coordinates.

One list looks like this (via print(*sortedList, sep = "n")):

([(1.0, 7.0), (4.0, 2.0), (8.0, 3.0), (3.0, 5.0), (1.0, 3.0), (6.0, 2.0)], 30.33773677780192)
([(3.0, 5.0), (4.0, 2.0), (6.0, 2.0), (8.0, 3.0), (1.0, 7.0), (1.0, 3.0)], 22.289030510712912)
([(8.0, 3.0), (1.0, 7.0), (4.0, 2.0), (1.0, 3.0), (3.0, 5.0), (6.0, 2.0)], 26.36262309267749)
([(4.0, 2.0), (3.0, 5.0), (1.0, 7.0), (1.0, 3.0), (6.0, 2.0), (8.0, 3.0)], 21.448897901624807)
([(8.0, 3.0), (4.0, 2.0), (6.0, 2.0), (3.0, 5.0), (1.0, 3.0), (1.0, 7.0)], 25.256431185781686)

What I would like to happen is that when it gets sorted, sortedList becomes:

([(4.0, 2.0), (3.0, 5.0), (1.0, 7.0), (1.0, 3.0), (6.0, 2.0), (8.0, 3.0)], 21.448897901624807)
([(3.0, 5.0), (4.0, 2.0), (6.0, 2.0), (8.0, 3.0), (1.0, 7.0), (1.0, 3.0)], 22.289030510712912)
([(8.0, 3.0), (4.0, 2.0), (6.0, 2.0), (3.0, 5.0), (1.0, 3.0), (1.0, 7.0)], 25.256431185781686)
([(8.0, 3.0), (1.0, 7.0), (4.0, 2.0), (1.0, 3.0), (3.0, 5.0), (6.0, 2.0)], 26.36262309267749)
([(1.0, 7.0), (4.0, 2.0), (8.0, 3.0), (3.0, 5.0), (1.0, 3.0), (6.0, 2.0)], 30.33773677780192)

But instead, the coordinates inside the arrays sort of get switched around in some way, which is definitely not what I want.

What I have been using is this code:

sortedList = list.sort_values(ascending=True)
print(*sortedList, sep = "n")

I haven’t really found anything that works, and when I try to sort "by columns", there is of course no attribute of columns in this list. I don’t think it’s feasible to add columns but that might be the only way. Is there another way?

Edit:

I’ve been looking into it and it seems like I might want to change it into a dictionary, although that might make it harder for me to change around later. I do also get a TypeError: unhashable type: 'list' when I try. If it’s any help this is to try to keep track of a range of TSP solutions for a genetic algorithm I’m trying to work on.

Asked By: bonepasta

||

Answers:

You could try the following:

unsortedList = [([(1.0, 7.0), (4.0, 2.0), (8.0, 3.0), (3.0, 5.0), (1.0, 3.0), (6.0, 2.0)], 30.33773677780192),
([(3.0, 5.0), (4.0, 2.0), (6.0, 2.0), (8.0, 3.0), (1.0, 7.0), (1.0, 3.0)], 22.289030510712912),
([(8.0, 3.0), (1.0, 7.0), (4.0, 2.0), (1.0, 3.0), (3.0, 5.0), (6.0, 2.0)], 26.36262309267749),
([(4.0, 2.0), (3.0, 5.0), (1.0, 7.0), (1.0, 3.0), (6.0, 2.0), (8.0, 3.0)], 21.448897901624807),
([(8.0, 3.0), (4.0, 2.0), (6.0, 2.0), (3.0, 5.0), (1.0, 3.0), (1.0, 7.0)], 25.256431185781686)]

sorted_List = sorted(
    unsortedList, 
    key=lambda x: x[1])

print(*sorted_List, sep='n')

Output:

([(4.0, 2.0), (3.0, 5.0), (1.0, 7.0), (1.0, 3.0), (6.0, 2.0), (8.0, 3.0)], 21.448897901624807)
([(3.0, 5.0), (4.0, 2.0), (6.0, 2.0), (8.0, 3.0), (1.0, 7.0), (1.0, 3.0)], 22.289030510712912)
([(8.0, 3.0), (4.0, 2.0), (6.0, 2.0), (3.0, 5.0), (1.0, 3.0), (1.0, 7.0)], 25.256431185781686)
([(8.0, 3.0), (1.0, 7.0), (4.0, 2.0), (1.0, 3.0), (3.0, 5.0), (6.0, 2.0)], 26.36262309267749)
([(1.0, 7.0), (4.0, 2.0), (8.0, 3.0), (3.0, 5.0), (1.0, 3.0), (6.0, 2.0)], 30.33773677780192)
Answered By: ScottC

You can use the key argument to sorted() to specify that Python compares the second element (the euclidean distance) in the tuple when sorting.

coordinates = [
    ([(1.0, 7.0), (4.0, 2.0), (8.0, 3.0), (3.0, 5.0), (1.0, 3.0), (6.0, 2.0)], 30.33773677780192),
    ([(3.0, 5.0), (4.0, 2.0), (6.0, 2.0), (8.0, 3.0), (1.0, 7.0), (1.0, 3.0)], 22.289030510712912),
    ([(8.0, 3.0), (1.0, 7.0), (4.0, 2.0), (1.0, 3.0), (3.0, 5.0), (6.0, 2.0)], 26.36262309267749),
    ([(4.0, 2.0), (3.0, 5.0), (1.0, 7.0), (1.0, 3.0), (6.0, 2.0), (8.0, 3.0)], 21.448897901624807),
    ([(8.0, 3.0), (4.0, 2.0), (6.0, 2.0), (3.0, 5.0), (1.0, 3.0), (1.0, 7.0)], 25.256431185781686),
]
sorted_coordinates = sorted(coordinates, key=lambda coord: coord[1])
print(*sorted_coordinates, sep="n")

Output:

([(4.0, 2.0), (3.0, 5.0), (1.0, 7.0), (1.0, 3.0), (6.0, 2.0), (8.0, 3.0)], 21.448897901624807)
([(3.0, 5.0), (4.0, 2.0), (6.0, 2.0), (8.0, 3.0), (1.0, 7.0), (1.0, 3.0)], 22.289030510712912)
([(8.0, 3.0), (4.0, 2.0), (6.0, 2.0), (3.0, 5.0), (1.0, 3.0), (1.0, 7.0)], 25.256431185781686)
([(8.0, 3.0), (1.0, 7.0), (4.0, 2.0), (1.0, 3.0), (3.0, 5.0), (6.0, 2.0)], 26.36262309267749)
([(1.0, 7.0), (4.0, 2.0), (8.0, 3.0), (3.0, 5.0), (1.0, 3.0), (6.0, 2.0)], 30.33773677780192)

Note: the sorted function creates a new list. You can also use the key argument with list.sort() if you would prefer to modify the list in place.

Answered By: Jack Taylor
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.