Scipy rankdata从最高到最低

时间:2014-06-16 20:46:05

标签: python numpy scipy

我想要实现的是一系列值的“从最高到最低”排名,基本上与rankdata相反

所以而不是:

a = [1,2,3,4,3,2,3,4]
rankdata(a).astype(int)
array([1, 2, 5, 7, 5, 2, 5, 7])

我想得到这个:

array([7, 6, 3, 1, 3, 6, 3, 1])

我无法在rankdata文档中找到任何内容来执行此操作。

4 个答案:

答案 0 :(得分:7)

可能是你不想要的愚蠢答案,但是你不能只减去长度,即从高等级到低等级的“反向”?

a = [1,2,3,4,3,2,3,4]
len(a) - rankdata(a).astype(int)
array([7, 6, 3, 1, 3, 6, 3, 1])

答案 1 :(得分:2)

另一种方法是将列表变为负数:

>>> from scipy.stats import rankdata
>>> a = [1,2,3,4,3,2,3,4]
>>> rankdata([-1 * i for i in a]).astype(int)
array([8, 6, 4, 1, 4, 6, 4, 1])

我发现这是一种更准确的方法,因为关系的分辨率在倒排的意义上得到了解决,而不是在自然等级的意义上。此外,在这种情况下,最小值将获得列表的最后位置的值,如通常所期望的那样。

答案 2 :(得分:0)

请牢记这两个答案的问题,当您使用argsort时,这将导致顺序不一致,仅在发生联系时才会出现。

例如

a=[1,1,2,3,4]

np.argsort(stats.rankdata(a))=array([0, 1, 2, 3, 4], dtype=int64
np.argsort(stats.rankdata([-1*i for i in a])) = array([4, 3, 2, 0, 1], dtype=int64)
np.argsort(5-stats.rankdata(a))= array([4, 3, 2, 0, 1], dtype=int64)

请注意,反转会导致领带顺序不一致(0和1),不会像原来那样翻转。

答案 3 :(得分:0)

(至少)有两种简单的方法可以做到这一点,但需要考虑一些微妙之处,我将在此过程中指出。

除非原始排名都是整数,否则转换为 int 不是一个好主意,在这种情况下您不需要它! rankdata() 中处理平局的默认方法是 "average",如果存在平局,这将导致分数排名。这大概是问题中转换为整数的原因。如果您使用其他方法之一,即 "max""min""ordinal",则排名已经是整数。我将假设这对 OP 来说是可以接受的,并从这里开始使用 method="max"

排名后反转(更快)

在这种方法中,我们先排名,然后颠倒顺序

len(a) - rankdata(a, method="max") + 1

给出

[8 6 3 1 3 6 3 1]

+ 1 是必需的,因为 rankdata() 返回的最大排名是 len(a),但我们希望我们的最低排名永远不会为 0。请注意,即使我们最初使用 {{1 }} 解决关系,我们得到 "max" 行为,由于逆转。例如,两次出现的 2 有效地位于第 6 和第 7 级,并且都被指定为 6,这是这些等级中的最小值,而不是最大值。

排名前反转(较慢)

这种方法需要遍历列表以将值乘以 -1,这会减慢速度:

"min"

给出

rankdata([-el for el in a], method="max")

在这种情况下,我们确实得到了 array([8, 7, 5, 2, 5, 7, 5, 2]) 行为,例如,两次出现的 2 有效地位于第 6 和第 7 级,并且都被分配了 7,这是这些等级中的最大值。这就是导致排名 1 没有出现的原因,因为我们在排名 1 和 2 处有平局,得到排名 2,这是这两个排名中的最大值。

时间

如果您希望在长输入上执行此操作,并且速度是一个问题,那么很明显第一种方法应该更快。例如,如果我们使用输入:

"max"

然后我们得到:

a = numpy.random.randint(100, size=1000).tolist()