我的数组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) )
如果您将r
和order
与numpy.sum( order == r)
进行比较,您会发现这不等于N.大约2%的订单不一样!
首先,我是否正确理解上述代码?其次,任何人都可以重现这个吗?我在Linux上使用Python 2.7.2,numpy 1.6.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)
首先放置较高的索引(对于绑定的行),这样当你尊重索引时,较低的索引是第一个。