我有以下元组列表:
[(1, 6), (2, 3), (2, 5), (2, 2), (1, 7), (3, 2), (2, 2)]
我想按元组中的第一个值对此列表进行排名,并按第二个值解析tie,以便输出如下所示:
[1, 5, 6, 3, 2, 7, 3]
我无法想到一个简单的方法,所以我一直在寻找像scipy.stats.rankdata这样的功能。但是,对于我的用例,它忽略了numpy.argsort中的 order 参数。我觉得我在这里遗漏了一些明显的东西,在这种情况下,我为没有更好地搜索我的答案而道歉!
修改
更好地解释我想要实现的目标:
给出元组列表
>>> l = [(1, 6), (2, 3), (2, 5), (2, 2), (1, 7), (3, 2), (2, 2)]
我想创建一个列表,其中包含列表 l 的元素的等级。例如,按每个元组中的第一个值排名:
>>> from scipy import stats
>>> stats.rankdata([i for i, j in l], method='min')
array([ 1., 3., 3., 3., 1., 7., 3.])
这几乎是我想要的,但是列表中有联系(有两次1.和四次3.)。
我想使用每个元组中的第二个值来打破关系,这样例如两个元组(2,2)将具有相同的排名,但是(2,3)和(2,5)将有不同的排名。结果列表应如下所示:
array([ 1., 5., 6., 3., 2., 7., 3.])
答案 0 :(得分:3)
Python自然地对序列进行排序。
>>> [x for x, y in sorted(enumerate([(1, 6), (2, 3), (2, 5), (2, 2), (1, 7), (3, 2), (2, 2)], start=1), key=operator.itemgetter(1))]
[1, 5, 4, 7, 2, 3, 6]
答案 1 :(得分:1)
感谢Ignacio Vazquez-Abrams' answer我设法找到了解决方案!它可能不是最有效的方法,但它确实有效。
>>> import operator
>>> from scipy import stats
>>> l = [(1, 6), (2, 3), (2, 5), (2, 2), (1, 7), (3, 2), (2, 2)]
>>> uniq = list(set(t for t in l))
>>> s = sorted(uniq)
>>> r = [s.index(i) for i in l]
>>> rank = stats.rankdata(r, method='min')
>>> rank
array([ 1., 5., 6., 3., 2., 7., 3.])