Python 不跳数排名(密排)
Python ranking without skipping number (dense rank)
使用 python 3.x 我想实现密集排名(如果排名重复,不要跳过数字)。我根据分数
对以下数组进行了排序
rank_list = [{'Id': 236966, 'score': 91.0}, {'Id': 237241, 'score': 82.0}, {'Id': 237077, 'score': 79.0}, {'Id': 237084, 'score': 78.0}, {'Id': 237080, 'score': 72.0}, {'Id': 237236, 'score': 71.0}, {'Id': 236979, 'score': 71.0}, {'Id': 236909, 'score': 67.0}, {'Id': 237174, 'score': 67.0}, {'Id': 237035, 'score': 66.0}]
我使用下面的代码来计算和分配 'rank' 字段,但是如果有重复的排名,代码会跳过一个排名
def rankFunc(e):
return e['score']
rank_list.sort(key = rankFunc, reverse=True)
sorted_scores = [obj['score'] for obj in rank_list]
ranks = [sorted_scores.index(x) for x in sorted_scores]
for index, obj in enumerate(rank_list):
obj['rank'] = ranks[index]+1
当前输出:
排名 = [1, 2, 3, 4, 5, 6, 6, 8, 8, 10]
我希望在不跳过任何数字的情况下分配等级,
排名 = [1, 2, 3, 4, 5, 6, 6, 7, 7, 8]
这个小辅助函数应该可以解决您的问题:
def rank_unique(x, **kwargs):
sx = sorted(set(x), **kwargs)
invsx = {s: i for i, s in enumerate(sx)}
return [1 + invsx[v] for v in x]
>>> rank_unique([r["score"] for r in rank_list], reverse=True)
[1, 2, 3, 4, 5, 6, 6, 7, 7, 8]
这个简单的解决方案将解决您的问题(假设数组已经排序)。
def assignRank(_list):
rank = 0
for i in range(len(_list)):
if _list[i]["score"] != _list[i-1]["score"]:
rank += 1
_list[i]["rank"] = rank
您可以使用具有 pandas 函数的密集排序方法
import pandas as pd
rank = pd.Series(sorted_scores).rank(method="dense",ascending=False).values
print(rank)
输出:
[1. 2. 3. 4. 5. 6. 6. 7. 7. 8.]
使用 python 3.x 我想实现密集排名(如果排名重复,不要跳过数字)。我根据分数
对以下数组进行了排序rank_list = [{'Id': 236966, 'score': 91.0}, {'Id': 237241, 'score': 82.0}, {'Id': 237077, 'score': 79.0}, {'Id': 237084, 'score': 78.0}, {'Id': 237080, 'score': 72.0}, {'Id': 237236, 'score': 71.0}, {'Id': 236979, 'score': 71.0}, {'Id': 236909, 'score': 67.0}, {'Id': 237174, 'score': 67.0}, {'Id': 237035, 'score': 66.0}]
我使用下面的代码来计算和分配 'rank' 字段,但是如果有重复的排名,代码会跳过一个排名
def rankFunc(e):
return e['score']
rank_list.sort(key = rankFunc, reverse=True)
sorted_scores = [obj['score'] for obj in rank_list]
ranks = [sorted_scores.index(x) for x in sorted_scores]
for index, obj in enumerate(rank_list):
obj['rank'] = ranks[index]+1
当前输出:
排名 = [1, 2, 3, 4, 5, 6, 6, 8, 8, 10]
我希望在不跳过任何数字的情况下分配等级,
排名 = [1, 2, 3, 4, 5, 6, 6, 7, 7, 8]
这个小辅助函数应该可以解决您的问题:
def rank_unique(x, **kwargs):
sx = sorted(set(x), **kwargs)
invsx = {s: i for i, s in enumerate(sx)}
return [1 + invsx[v] for v in x]
>>> rank_unique([r["score"] for r in rank_list], reverse=True)
[1, 2, 3, 4, 5, 6, 6, 7, 7, 8]
这个简单的解决方案将解决您的问题(假设数组已经排序)。
def assignRank(_list): rank = 0 for i in range(len(_list)): if _list[i]["score"] != _list[i-1]["score"]: rank += 1 _list[i]["rank"] = rank
您可以使用具有 pandas 函数的密集排序方法
import pandas as pd
rank = pd.Series(sorted_scores).rank(method="dense",ascending=False).values
print(rank)
输出:
[1. 2. 3. 4. 5. 6. 6. 7. 7. 8.]