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)
答案 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 (它们是不同的对象)。因此,在相同对象的每个“群集”中,根据排序算法,它们的顺序可能不同。