我有一份清单
data = [ ['fruit', 'apple', 'v1', 'data 1'],
['fruit', 'apple', 'v2', 'data 2'],
['fruit', 'apple', 'v3', 'data 3'],
['fruit', 'banana', 'v1', 'data 4'],
['fruit', 'banana', 'v2', 'data 5'],
['animal', 'dog', 'v1', 'data 6'] ]
如何根据前2列并使用最高v?
中的数据进行折叠result = [ ['fruit', 'apple', 'v3', 'data 3'],
['fruit', 'banana', 'v2', 'data 5'],
['animal', 'dog', 'v1', 'data 6'] ]
列表在第一列中排序,但第二列未排序。我的解决方案基于这样的假设,即两个列都已排序,因此它不起作用,我不知道从哪里开始。
previous = []
result = []
for a, b, c, d in data:
if not all(x in previous for x in [a, b]):
final.append([a, b, c, d])
previous = [a, b, c, d]
else:
if previous[2] < c:
final[-1][2] = c
final[-1][3] = d
previous = [a, b, c, d]
print result
答案 0 :(得分:4)
这是一种方式。
import pandas as pd
data = [ ['fruit', 'apple', 'v1', 'data 1'],
['fruit', 'apple', 'v2', 'data 2'],
['fruit', 'apple', 'v3', 'data 3'],
['fruit', 'banana', 'v1', 'data 4'],
['fruit', 'banana', 'v2', 'data 5'],
['animal', 'dog', 'v1', 'data 6'] ]
df = pd.DataFrame(data, columns=['Col1', 'Col2', 'Col3', 'Col4'])
df['Grouper'] = df['Col1'] + df['Col2']
df['Order'] = df['Col3'].map(lambda x: int(x[-1]))
df = df.sort_values(['Grouper', 'Order'], ascending=[True, False])\
.drop_duplicates('Grouper')\
.drop(['Grouper', 'Order'], 1)
lst = df.values.tolist()
# [['animal', 'dog', 'v1', 'data 6'],
# ['fruit', 'apple', 'v3', 'data 3'],
# ['fruit', 'banana', 'v2', 'data 5']]
答案 1 :(得分:4)
您可以使用:
("fruit", "banana")
)>>> import itertools >>> >>> data = [['fruit', 'apple', 'v1', 'some data'], ... ['fruit', 'apple', 'v2', 'some data'], ... ['fruit', 'apple', 'v3', 'some data'], ... ['fruit', 'banana', 'v1', 'some data'], ... ['fruit', 'banana', 'v2', 'some data'], ... ['animal', 'dog', 'v1', 'some data']] >>> >>> [max(item[1], key=lambda x: (x[2][0], int(x[2][1:]))) for item in itertools.groupby(data, key=lambda x: (x[0], x[1]))] [['fruit', 'apple', 'v3', 'some data'], ['fruit', 'banana', 'v2', 'some data'], ['animal', 'dog', 'v1', 'some data']]
或者您可以采用(老式的)手动方式(例如使用帮助字典):
>>> helper_dict = dict() >>> for item in data: ... item_v = helper_dict.get((item[0], item[1]), (None, None, "v0"))[2] ... if (item_v[0], int(item_v[1:])) < (item[2][0], int(item[2][1:])): ... helper_dict[(item[0], item[1])] = item ... >>> print(list(helper_dict.values())) [['fruit', 'apple', 'v3', 'some data'], ['animal', 'dog', 'v1', 'some data'], ['fruit', 'banana', 'v2', 'some data']]
答案 2 :(得分:2)
另一种可能的方法:
(1)创建一个映射第一列和第二列索引的字典,并映射每对的最新索引。这样就可以在最后正确地对数据进行排序。
(2)创建第一列和第二列的所有不同分组的collections.defaultdict
。
(3)从(2)中找出每个分组的最大v值,并将其与其余元素组合。这将作为折叠列表返回。
(4)根据(1)对折叠列表进行排序。
示例代码:
from collections import defaultdict
data = [['fruit', 'apple', 'v1', 'data 1'],
['fruit', 'apple', 'v2', 'data 2'],
['fruit', 'apple', 'v3', 'data 3'],
['fruit', 'banana', 'v1', 'data 4'],
['fruit', 'banana', 'v2', 'data 5'],
['animal', 'dog', 'v1', 'data 6']]
groups = defaultdict(list)
sort_map = {}
for i, (fst, snd, *rest) in enumerate(data):
sort_map[(fst, snd)] = i
groups[(fst, snd)].append(rest)
result = sorted((list(k) + max(v) for k, v in groups.items()),
key=lambda x: sort_map[(x[0], x[1])])
print(result)
<强>输出:强>
[['fruit', 'apple', 'v3', 'data 3'],
['fruit', 'banana', 'v2', 'data 5'],
['animal', 'dog', 'v1', 'data 6']]