2

I have a pandas DataFrame constructed like so:

l1 = [[[1,2], [3,5]], [[3,2], [5,2]]]
l2 = [[[9,2], [4,5]], [[4,3], [2,7]]]
l3 = [[[3,3], [4,4]], [[6,3], [4,6]]]
l4 = [[[4,4], [3,5]], [[2,5], [3,4]]]
small_df = pd.DataFrame({'col': [l1, l2, l3, l4]})

print(small_df)
col
0   [[[1, 2], [3, 5]], [[3, 2], [5, 2]]]
1   [[[9, 2], [4, 5]], [[4, 3], [2, 7]]]
2   [[[3, 3], [4, 4]], [[6, 3], [4, 6]]]
3   [[[4, 4], [3, 5]], [[2, 5], [3, 4]]]

I would like to first sort the inner list of points so that [[9, 2], [4, 5]] becomes [[4, 5], [9, 2]], then sort the outer list so that [[[4, 5], [9, 2]], [[2, 7], [4, 3]]] becomes [[[2, 7], [4, 3]], [[4, 5], [9, 2]]]. I have figure out how to sort the outer list like so:

small_df["sorted"] = small_df["col"].apply(sorted)
small_df
    col                                     sorted
0   [[[1, 2], [3, 5]], [[3, 2], [5, 2]]]    [[[1, 2], [3, 5]], [[3, 2], [5, 2]]]
1   [[[9, 2], [4, 5]], [[4, 3], [2, 7]]]    [[[4, 3], [2, 7]], [[9, 2], [4, 5]]]
2   [[[3, 3], [4, 4]], [[6, 3], [4, 6]]]    [[[3, 3], [4, 4]], [[6, 3], [4, 6]]]
3   [[[4, 4], [3, 5]], [[2, 5], [3, 4]]]    [[[2, 5], [3, 4]], [[4, 4], [3, 5]]]

How can I sort the inner list first though? I would like to end up with this:

col                                         goal
0   [[[1, 2], [3, 5]], [[3, 2], [5, 2]]]    [[[1, 2], [3, 5]], [[3, 2], [5, 2]]]
1   [[[9, 2], [4, 5]], [[4, 3], [2, 7]]]    [[[2, 7], [4, 3]], [[4, 5], [9, 2]]]
2   [[[3, 3], [4, 4]], [[6, 3], [4, 6]]]    [[[3, 3], [4, 4]], [[4, 6], [6, 3]]]
3   [[[4, 4], [3, 5]], [[2, 5], [3, 4]]]    [[[2, 5], [3, 4]], [[3, 5], [4, 4]]]

Ideally, I would like to do all the sorting at the same time so it's as efficient as possible.

2
  • Are all the sublist of the same length? Commented Apr 21, 2020 at 15:09
  • Yes, they are. Your answer is exactly what I was looking for. Thanks! Commented Apr 21, 2020 at 15:11

2 Answers 2

3

Sort first each of the inner list, then the container list:

import pandas as pd

l1 = [[[1, 2], [3, 5]], [[3, 2], [5, 2]]]
l2 = [[[9, 2], [4, 5]], [[4, 3], [2, 7]]]
l3 = [[[3, 3], [4, 4]], [[6, 3], [4, 6]]]
l4 = [[[4, 4], [3, 5]], [[2, 5], [3, 4]]]
small_df = pd.DataFrame({'col': [l1, l2, l3, l4]})


def sort(lst):
    """Sort inner list and then sort container list"""
    return sorted(sorted(e) for e in lst)


small_df['sorted'] = small_df['col'].apply(sort)
print(small_df)

Output

                                    col                                sorted
0  [[[1, 2], [3, 5]], [[3, 2], [5, 2]]]  [[[1, 2], [3, 5]], [[3, 2], [5, 2]]]
1  [[[9, 2], [4, 5]], [[4, 3], [2, 7]]]  [[[2, 7], [4, 3]], [[4, 5], [9, 2]]]
2  [[[3, 3], [4, 4]], [[6, 3], [4, 6]]]  [[[3, 3], [4, 4]], [[4, 6], [6, 3]]]
3  [[[4, 4], [3, 5]], [[2, 5], [3, 4]]]  [[[2, 5], [3, 4]], [[3, 5], [4, 4]]]
Sign up to request clarification or add additional context in comments.

Comments

1

Alternative with explode and map

small_df['sorted_col'] = (small_df['col'].explode().map(sorted).sort_values()
                           .groupby(level=0).agg(list))
print(small_df)

                                    col                            sorted_col
0  [[[1, 2], [3, 5]], [[3, 2], [5, 2]]]  [[[1, 2], [3, 5]], [[3, 2], [5, 2]]]
1  [[[9, 2], [4, 5]], [[4, 3], [2, 7]]]  [[[2, 7], [4, 3]], [[4, 5], [9, 2]]]
2  [[[3, 3], [4, 4]], [[6, 3], [4, 6]]]  [[[3, 3], [4, 4]], [[4, 6], [6, 3]]]
3  [[[4, 4], [3, 5]], [[2, 5], [3, 4]]]  [[[2, 5], [3, 4]], [[3, 5], [4, 4]]]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.