np.argsort()排名靠前

时间:2019-04-06 23:24:33

标签: python arrays numpy sorting

np.argsort()如何处理领带?

test = [1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0]
np.argsort(test)

为什么索引20在结果中排​​在首位?

我检查了其他资源,但找不到解释。是否在有联系的地方随机分配索引?谢谢!

array([20,  4,  5,  8,  9, 10, 11, 23, 17, 14, 15,  0, 22, 21, 19, 18, 12,
       13,  7,  6,  3,  2,  1, 16, 24], dtype=int64) 

3 个答案:

答案 0 :(得分:0)

numpy.argsort()返回将对数组元素进行排序的数组索引。如果存在重复的条目,则返回的索引取决于用于对数组进行排序的排序算法的类型。根据此选择,您可能会看到不同的结果,如下所示:

# input
In [90]: a
Out[90]: 
array([1., 1., 1., 1., 0., 0., 1., 1., 0., 0., 0., 0., 1., 1., 0., 0., 1.,
       0., 1., 1., 0., 1., 1., 0., 1.])

# more intuitive
In [85]: np.argsort(a, kind='mergesort')
Out[85]: 
array([ 4,  5,  8,  9, 10, 11, 14, 15, 17, 20, 23,  0,  1,  2,  3,  6,  7,
       12, 13, 16, 18, 19, 21, 22, 24])

# default choice
In [86]: np.argsort(a, kind='quicksort')
Out[86]: 
array([20,  4,  5,  8,  9, 10, 11, 23, 17, 14, 15,  0, 22, 21, 19, 18, 12,
       13,  7,  6,  3,  2,  1, 16, 24])

In [88]: np.argsort(a, kind='heapsort')
Out[88]: 
array([17, 11, 20,  8, 15, 14, 23, 10,  4,  9,  5, 13,  6, 12, 24,  2, 21,
       19, 18, 16,  7, 22,  3,  1,  0])

# more intuitive
In [89]: np.argsort(a, kind='stable')
Out[89]: 
array([ 4,  5,  8,  9, 10, 11, 14, 15, 17, 20, 23,  0,  1,  2,  3,  6,  7,
       12, 13, 16, 18, 19, 21, 22, 24])

答案 1 :(得分:0)

我认为对此没有一个答案

>>> np.argsort(test, kind="quicksort")
array([20,  4,  5,  8,  9, 10, 11, 23, 17, 14, ... ])
>>> np.argsort(test, kind="mergesort")
array([ 4,  5,  8,  9, 10, 11, 14, 15, 17, 20, ... ])
>>> np.argsort(test, kind="stable")
array([ 4,  5,  8,  9, 10, 11, 14, 15, 17, 20, ... ])
>>> np.argsort(test, kind="heapsort")
array([17, 11, 20,  8, 15, 14, 23, 10,  4,  9, ... ])

我想我们可以read the code真正理解为什么会发生这种情况,但是我最好的猜测是顺序是任意的,可能是结果而不是选择。

反之,如果您需要一个用于关系的自定义子分类,则可以使用np.unique。作为示例,我将对quicksort的输出进行排序,使其模仿诸如mergesort的输出:

ranks = np.argsort(test, kind="quicksort")
# split the indexes so we can sort them independently:
_, counts = np.unique(test, return_counts=True)
cuts = np.cumsum(counts)[:-1]
rank_bins = np.split(ranks, cuts)
sorted_rank_bins = [np.sort(b) for b in rank_bins]
# glue them back together: 
ranks = np.concatenate(sorted_rank_bins)

现在ranks包含:

array([ 4,  5,  8,  9, 10, 11, 14, 15, 17, 20, 23,  0,  1,  2,  3,  6,  7,
       12, 13, 16, 18, 19, 21, 22, 24])

这个解决方案很长,我想可能会有一个更短/更快的解决方案。同样在这里,我只是根据索引的值对索引进行了排序,但是您可以想象其他任何顺序。

答案 2 :(得分:0)

其他答案提到np.argsort返回将对数组进行排序的索引,并且这些索引取决于排序算法,例如:

>>> np.random.seed(0)  # for reproducibility
>>> a = np.random.randint(0, 5, 20)
>>> np.argsort(a, kind='mergesort')
array([ 2,  6,  8, 11, 16,  0,  1,  3, 12, 17, 18, 19,  9,  5,  7, 10, 13,
       14, 15,  4])
>>> np.argsort(a, kind='quicksort')
array([ 2, 16, 11,  6,  8,  0, 17, 12, 18, 19,  3,  1,  9, 10,  5, 13, 14,
       15,  7,  4])

我想进入为什么

简而言之,排序算法可以是稳定的,也可以是不稳定的。在这种情况下,稳定性意味着它们不会更改比较相等的元素的相对顺序

想象一下,我们用一些值“标记”元素以表明它们是不同的对象,例如:

unsorted = [4 (star), 3 (cube), 3 (star), 4 (cube)]

稳定排序(例如mergesort)将总是 返回以下内容:

sorted = [3 (cube), 3 (star), 4 (star), 4 (cube)]

这是因为3 (cube)3 (star)之前,而4 (star)4 (cube)之前。

相反,非稳定排序(例如quicksort)可以按任何顺序返回元素,除了所有3必须先于所有4之外。

当我们将其应用于最初的问题时,我们可以理解它产生的原因。即使元素具有相同的 value (它们比较相等),它们也不具有相同的 identity (它们是不同的对象)。因此,在相同对象的每个“群集”中,根据排序算法,它们的顺序可能不同。