python - 如何在python中复制SQL窗口排名
问题描述
如果我们假设我有一个包含 id、数据和分数值的输入数据集(列表列表),我想过滤到每个 id 的最高得分日。通常在 SQL 中,我会使用 window 和 rank 函数来执行此操作,但我想不出 Pythonic 的方法来解决这个问题。
这是一个本机解决方案:
data = [
["123", "11/11/11", "0.5"],
["555", "12/11/11", "0.3"],
["555", "13/11/11", "0.9"],
["123", "14/11/11", "0.8"]
]
_sorted = sorted( data, key=lambda record: (record[0], record[2]), reverse=True)
output = []
last_id_seen = None
for record in _sorted:
if record[0] is last_id_seen:
continue
last_id_seen = record[0]
output.append(record)
print(output)
# output
# [['555', '13/11/11', '0.9'], ['123', '14/11/11', '0.8']]
但这感觉很笨拙,我不知道这种排序将如何支持更复杂的情况。另外,我最好避免使用 Pandas 或 Numpy 解决方案,因为我认为这里不需要它们。
建议?
解决方案
data = [
["123", "11/11/11", "0.5"],
["555", "12/11/11", "0.3"],
["555", "13/11/11", "0.9"],
["123", "14/11/11", "0.8"]
] # data
from itertools import groupby # groupby function
# Sort on id and score
_sorted = sorted( data, key=lambda record: (record[0], record[2]), reverse=True)
for k, v in groupby(_sorted, lambda x: x[0]): # group by id
# k: ids, v: groups
print(list(v)[0]) # print
我使用了 itertools 中的 groupby 来对 ID 列上的排序数组进行分组。由于我们对 score 键的顺序是相反的,因此获取v[0]
每个组的第一个元素就足够了。
推荐阅读
- mysql - MySQL:基于另一个并不总是具有匹配值的连接表进行排序
- android - 如何为 Launcher3 默认工作区设置最喜欢的应用程序 - Android Source
- css - 将图像放入使用纯 CSS 完成的基本梯形?
- c++ - 将 ProcessEntry32.szExeFile 与用户输入的数据进行比较时,C++ _wcsicmp 代码未编译
- javascript - 你如何让用户在 html 中为 select 标签选择默认值?
- php - 如何在 linux 上的 git hook 中重新启动进程
- sql - 如何从错误消息sql server中查找表名和列名
- javascript - 在循环中调用 resolveLocalFileSystemURL
- git - Git提交然后签出和签出然后提交之间有区别吗?
- c# - 如何使用 philips 强大的散列算法使用 C# 提取 32 位音频指纹?