MATLAB sort()vs Numpy argsort() - 如何匹配结果?

时间:2016-09-14 06:46:17

标签: python matlab sorting numpy

我正在将一个MATLAB代码移植到Python的Numpy。

在MATLAB(实际上是Octave)中,我有类似的东西:

>> someArr = [9, 8, 7, 7]
>> [~, ans] = sort(someArr, 'descend')
   ans =
   1   2   3   4

所以在Numpy,我正在做:

>>> someArr = np.array([9, 8, 7, 7])
>>> np.argsort(someArr)[::-1]
array([0, 1, 3, 2])

我在MATLAB中获得了1, 2, 3, 4而在Numpy上获得了0, 1, 3, 2,而我在Numpy上需要0, 1, 2, 3

我相信它是由于每个函数中使用的排序算法,但我检查过,看起来两者都使用“quicksort”(请参阅​​herehere)。

如何将Numpy的解决方案与MATLAB解决方案相匹配?

3 个答案:

答案 0 :(得分:4)

为了使这项工作,我们需要有点聪明。 numpy没有'descend'类似物。你通过反转排序的结果来模仿它(最终你正在撤消)。

我不确定matlab如何完成它,但他们声称使用了stable variant of quicksort。具体来说,对于降序排序:

  

如果标志为'descend',则输出在返回之前反转。在逆转之后,我们运行索引向量排序以恢复稳定性。

octave似乎在此处效仿。

由于它们的排序是稳定的,因此可以保证输入中的相等值的顺序将保留在输出中。另一方面,numpy对它的快速排序没有做出这样的保证。如果我们想要一个稳定的numpy排序,我们需要使用mergesort

>>> np.argsort(someArr, kind='mergesort')
array([2, 3, 1, 0])

好的,这个输出很有意义。 someArr[2] == someArr[3],第三个元素出现在第四个元素之前,因此2在输出中3之前是明智的(没有保证稳定的排序算法,我们无法做出此声明) 。现在来了聪明的踩踏......你想要“降序”值,而不是颠倒argsort的输出,为什么我们不否定输入呢?这将会产生比较低数字排序更大数字排序的效果,正如降序排序那样......

>>> np.argsort(-someArr, kind='quicksort')
array([0, 1, 2, 3])

现在我们正在谈论!由于mergesort保证稳定,因此出现在较低索引处的元素(具有相等的值)将首先出现在输出中 - 就像matlab / octave一样。好的。

答案 1 :(得分:0)

您可以选择不同的排序算法。将其更改为heapsort对我有用:

>> np.argsort(someArr, kind="heapsort")[::-1]
array([0, 1, 2, 3], dtype=int32)

编辑:这仅适用于我看过的一些测试用例。 [9, 8, 7, 7, 4, 1, 1]它停止工作。我的回答可能不是一个好的解决方案。

答案 2 :(得分:0)

尝试

np.argsort(dataset,axis=-1,kind='stable')