[英]How to sort a list of tuples by the first element in each tuple, and pick the tuple with the largest last element in each group
Here I have a list of n k-tuples (Here I set n = 4, k = 5)这里我有一个 n 个 k 元组的列表(这里我设置 n = 4,k = 5)
A = [(1, 3, 5, 6, 6), (0, 1, 2, 4, 5), (1, 9, 8, 3, 5), (0, 2, 3, 5, 7)]
I hope to sort these tuples by their first element, so it will be 2 groups.我希望按第一个元素对这些元组进行排序,因此将分为 2 组。 And in each group, I want to select only 1 tuple whose last element is the largest.在每个组中,我只想 select 最后一个元素最大的 1 个元组。 So in this situation, I hope my output of the function to be a list of tuple, such as所以在这种情况下,我希望我的 function 中的 output 是一个元组列表,比如
[(1, 3, 5, 6, 6),
(0, 2, 3, 5, 7)]
Below is my attempt, and it seems it does not work well以下是我的尝试,但似乎效果不佳
import pandas as pd
import numpy as np
def f (sample):
data = pd.DataFrame(sample)
grouped_data = data.groupby(0)
maximums = grouped_data.max(4)
result = list(maximums.to_records(index = False))
return result
I want to know if this could be accomplished by writing a dict?我想知道这是否可以通过写一个 dict 来完成? If so, how?如果是这样,如何? Any hint or help is welcome.欢迎任何提示或帮助。
You can use itertools.groupby
for this:您可以为此使用itertools.groupby
:
import itertools
def by_first_element(t):
return t[0]
def by_last_element(t):
return t[-1]
sorted_A = sorted(A, key=by_first_element)
groups = [[*g] for _, g in itertools.groupby(sorted_A, key=by_first_element)]
max_of_each_group = [max(g, key=by_last_element) for g in groups]
Output: Output:
[(0, 2, 3, 5, 7), (1, 3, 5, 6, 6)]
Alternatively, yes, you can use a dictionary:或者,是的,您可以使用字典:
groups = {}
for t in A:
groups[t[0]] = groups.get(t[0], []) + [t]
max_of_each_group = [max(g, key=lambda t: t[-1]) for g in groups.values()]
If you want max_of_each_group
sorted, then如果你想要max_of_each_group
排序,那么
>>> sorted(max_of_each_group, key=lambda t: t[0])
[(0, 2, 3, 5, 7), (1, 3, 5, 6, 6)]
This is trivial to accomplish with a dict.用 dict 完成这件事是微不足道的。 In fact, since you are going to do a reduction operation on the group, you can do this quite space-efficiently doing the reduction at each step:事实上,由于您要对组进行缩减操作,因此您可以在每一步进行缩减时非常节省空间:
>>> A = [(1, 3, 5, 6, 6), (0, 1, 2, 4, 5), (1, 9, 8, 3, 5), (0, 2, 3, 5, 7)]
>>> result = {}
>>> for tup in A:
... first = tup[0]
... result[first] = max(tup, result.get(first, tup), key=lambda x:x[-1])
...
>>> result
{1: (1, 3, 5, 6, 6), 0: (0, 2, 3, 5, 7)}
>>> list(result.values())
[(1, 3, 5, 6, 6), (0, 2, 3, 5, 7)]
Another valid approach is to do the grouping step first then a reduction step, this is probably more generalizable:另一种有效的方法是先进行分组步骤,然后进行归约步骤,这可能更具有普遍性:
>>> result = {}
>>> grouper = {}
>>> for tup in A:
... grouper.setdefault(tup[0],[]).append(tup)
...
>>> grouper
{1: [(1, 3, 5, 6, 6), (1, 9, 8, 3, 5)], 0: [(0, 1, 2, 4, 5), (0, 2, 3, 5, 7)]}
And to reduce:并减少:
>>> {k: max(v, key=lambda x:x[-1]) for k,v in grouper.items()}
{1: (1, 3, 5, 6, 6), 0: (0, 2, 3, 5, 7)}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.