Numpy的argsort与Scipy.stats的rankdata区别

7

我最近使用了这两个函数,并希望听取任何人对以下问题的意见:

  • argsort和rankdata在其用途上有根本区别吗?
  • 它们之间是否存在性能优势?(特别是:大型数组和小型数组的性能差异?)
  • 导入rankdata的内存开销是多少?

提前感谢。

p.s. 我无法创建新标签'argsort'或'rankdata'。如果有任何拥有足够地位的人觉得它们应该添加到此问题中,请添加。


2
看一下 rankdata 的代码。它首先做的事情之一是 argsort。但它并不只是简单地返回排序结果。你要排序的是什么类型的数据? - hpaulj
argsort本身不进行排名。有关使用argsortrankdata进行排名的更多信息,请参见此问题和答案 - Warren Weckesser
@hpaulj 我正在为机器学习课程使用UCI蘑菇数据集,并需要按重要性对特征进行排名。 - Boreal Coder
@WarrenWeckesser 谢谢 - 我已经阅读了您提供的那个线程(并做出贡献)。它似乎更喜欢argsort而不是rankdata,尽管要注意调用argsort两次可能会有性能惩罚。原始评论已经几年了 - 自那时以来,这两个函数是否都被优化到足以成为排列数组的明显赢家? - Boreal Coder
那里接受的答案展示了使用argsort进行排名的高效方法。除了从0开始而不是1之外,它提供了与rankdata(x, method='ordinal')相同的排名。如果这是您需要的排名方式,那么请使用接受的答案中的argsort方法-它比rankdata少一些开销,因此速度会更快。(请注意,它将以不同的方式处理重复值。)如果您不想实现自己的排名函数,或者需要它提供的其他排名方法之一,则rankdata非常好用。 - Warren Weckesser
1个回答

6

argsort和rankdata在目的上有根本的区别吗?

在我看来,它们略有不同。第一个会给你数据排序后的位置,而第二个是数据的排名。在存在并列的情况下,这种差异可能会变得明显:

import numpy as np
from scipy import stats

a = np.array([ 5, 0.3,  0.4, 1, 1, 1, 3, 42])
almost_ranks = np.empty_like(a)
almost_ranks[np.argsort(a)] = np.arange(len(a))
print(almost_ranks)
print(almost_ranks+1)
print(stats.rankdata(a))

结果为(注意 3. 4. 54. 4. 4 的区别):

[6. 0. 1. 2. 3. 4. 5. 7.]
[7. 1. 2. 3. 4. 5. 6. 8.]
[7. 1. 2. 4. 4. 4. 6. 8.]

“一个相对另一个有性能优势吗?(特别是:大型与小型数组性能差异?)”
“这两种算法在复杂度上似乎都是O(NlgN)。我认为numpy实现会稍微快一些,因为它的开销要小一些,而且它是numpy。但你应该自己测试一下……检查scipy.rankdata的代码,目前(我的python……)它似乎会调用np.unique等其他函数,所以我猜在实践中它会花费更多时间……”
“导入rankdata会带来什么内存开销?”
“嗯,你需要导入scipy,如果之前没有导入过,那么它就是scipy的开销……”

要添加一些统计数据、排名和返回一个包含100个整数的数组的索引,argsort 平均需要1.7微秒,而 rankdata 则需要53.9微秒,这之间的差距相当大;当涉及到一个包含1,000,000个整数的数组时,argsort 的效率大约高出30%(73.5毫秒对比107毫秒)。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接