numpy 1.6.1 argsort()奇怪的行为?

时间:2014-09-05 12:48:56

标签: python arrays sorting numpy

我的数组data的形状为(N,6)。我在最后一列对这个数组进行排序,以便:

sortx = numpy.argsort( data[:,-1] )[::-1]
sortedData = data[ sortx, : ]

其中[::-1]用于将列从高到低排序,而不是从低到高排序,数据是 float64 。然后我将这个已排序的数组保存到.npy文件中,如下所示:

numpy.save( 'file.npy', sortedData )

但是,当我再次加载数组并检查数据的排序时,它似乎没有按顺序排列!它只是一些行,而不是所有行都是奇怪的。

data_again = numpy.load( 'file.npy' )
order = numpy.argsort( data_again[:,-1] )[::-1]
r = numpy.arange( len(data_again) )

如果您将rordernumpy.sum( order == r)进行比较,您会发现这不等于N.大约2%的订单不一样!

首先,我是否正确理解上述代码?其次,任何人都可以重现这个吗?我在Linux上使用Python 2.7.2,numpy 1.6.1。

更新:即使在第一次排序之后和保存之前,也会发生此行为。所以它与排序本身有关。排序列中有重复的值。

1 个答案:

答案 0 :(得分:4)

如果最后一列有重复的值,我可以重现这些症状:

import numpy as np
np.random.seed(0)
data = np.random.random((8,2))
data[::2,-1] = data[1::2,-1]
print(data)
# [[ 0.5488135   0.54488318]
#  [ 0.60276338  0.54488318]
#  [ 0.4236548   0.891773  ]
#  [ 0.43758721  0.891773  ]
#  [ 0.96366276  0.52889492]
#  [ 0.79172504  0.52889492]
#  [ 0.56804456  0.0871293 ]
#  [ 0.07103606  0.0871293 ]]
sortx = np.argsort( data[:,-1] )[::-1]
sorted_data = data[ sortx, : ]

order = np.argsort( sorted_data[:,-1] )[::-1]
r = np.arange( len(sorted_data) )
print(order)
# [1 0 3 2 5 4 7 6]
print(r)
# [0 1 2 3 4 5 6 7]
print(np.allclose(order, r))
# False

np.argsort默认使用快速排序。 Quicksort不稳定,因此绑定行的顺序不一定与原始数据的顺序相同。

但是,即使您使用mergesort之类的稳定排序,当反转结果np.argsort时,对于绑定的行, >更高的指数排在第一位。

因此,当您第二次致电np.argsort时,您的order不会等于r

您可以通过对最终列进行排序并使用np.arange(len(data),0,-1)作为决胜局来生成该订单:

sortx = np.lexsort((np.arange(len(data),0,-1), data[:,-1]))[::-1]
sorted_data = data[ sortx, : ]

order = np.lexsort((np.arange(len(data),0,-1), sorted_data[:,-1]))[::-1]
r = np.arange( len(sorted_data) )
print(order)
# [0 1 2 3 4 5 6 7]
print(r)
# [0 1 2 3 4 5 6 7]
print(np.allclose(order, r))
# True

使用np.arange(len(data),0,-1)首先放置较高的索引(对于绑定的行),这样当你尊重索引时,较低的索引是第一个。