2014-09-05 3 views
2

배열 data은 모양이 (N,6)입니다. I는 최종 열에 의해 이러한 배열을 정렬하고되도록 다음 [::-1] 높은 대신 로우, 하이에서 로우로 열을 정렬하기 위해 사용되며, 데이터 float64이다numpy 1.6.1 argsort() 이상한 행동?

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

. 다음과 같이 나는 다음 .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)) 

당신이 numpy.sum(order == r)rorder을 비교하면, 당신은 동일한 순서로이 동일 N. 2 % 주위하지 않습니다되지 않습니다보세요!

먼저 위 코드를 올바르게 이해하고 있습니까? 둘째, 누구도 이것을 재현 할 수 있습니까? 리눅스에서 파이썬 2.7.2, numpy 1.6.1을 사용하고 있습니다.

업데이트 :이 문제는 첫 번째 정렬 후에 저장하기 전에도 발생합니다. 그래서 정렬 자체와 관련이 있습니다. 정렬 된 열에 중복 값이 ​​있습니다. 마지막 열 값을 반복 한 경우

+2

문제를 격리하기 위해 할 수있는 일이 많이 있습니다. 중간 저장 없이도 발생합니까? 예를 들면? –

+1

데이터의 dtype은 무엇입니까? 아마도 숫자처럼 보이는 문자열일까요? 문제를 재현하는 '데이터'조각을 게시하면 많은 도움이됩니다. – unutbu

+0

안녕하세요. 감사. 저장하지 않고 발생합니다. dtype은 float64입니다. –

답변

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는 안정적이지 않으므로 묶인 행의 순서가 원본 데이터와 반드시 같은 순서가 아니어도됩니다.

그러나, 당신이 높은 인덱스가 먼저, 연결되어 행에 대해, np.argsort의 결과를 역 때 같은 mergesort으로 안정적인 종류를 사용하더라도.

따라서 np.argsort을 다시 호출하면 orderr과 같지 않습니다.

당신은 마지막 열을 정렬 및 타이 브레이커로 np.arange(len(data),0,-1)를 사용하여 순서를 생산할 수

:

것을 당신이 인덱스를 공경 그래서 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 

, 낮은 지수가 첫 번째입니다.

+0

나는 본다! 평이한 언어로 작성해 주셔서 감사합니다. 건배. –