2017-02-01 6 views
5

나는 np.ndarray이 그 배열을? 내가 원하는 경우에 따라서, 4는 가장 작은 그것은m 가장 작은 값은

[(0,1,1),(0,4,1),(3,4,1),(0,3,2)] 

어디에 (행, COL, 발은) 위의 표기법이 될 것입니다.

값이 여러 개인 경우 하나가 임의로 선택됩니다. 예를 들어, 3 개가 있고 그 다음으로 가장 작은 값은 2이지만 (0,3,2), (1,2,2), (1,4,2)가 모두 가능한 선택입니다.

기본적으로 위 삼각 행렬에서 해당 형식의 k 개의 가장 작은 값을 효율적으로 추출 할 수 있습니까 (행렬은 위의 예보다 훨씬 큽니다). 나는 정사각형 형태 인 nsmallest를 사용하여 그것을 평평하게하려했지만, 인덱스와 값을 정렬하는 데 문제가있었습니다. 감사! 이 같은

+0

가능한 복제본 http://stackoverflow.com/questions/30577375/have-numpy-argsort-return-an-array-of-2d-indices 'np.dstack (np.unravel_index (np.argsort (tri .ravel()), arr.shape))' 왼쪽에 값이 압축되어 있습니다. – 3novak

+0

이것은 도움이 될 수 있습니다 : http://stackoverflow.com/a/10337643/149076 ... 가장 작은 것보다는 가장 큰 K 항목을 찾는 것입니다. 또 다른 방법은 numpy.ndenumerate()를 사용하여 heapq.nsmallest() 항목을 가져 오기 전에 힙에 병합하는 좌표 및 값의 평면 목록을 생성하는 것입니다. –

+0

게시 된 솔루션 중 어느 것이 적합합니까? – Divakar

답변

2

- 성능

r,c = np.unravel_index(a.ravel().argsort()[:4], a.shape) 
out = zip(r,c,a[r,c]) 

np.argpartition을 사용하는 것이 좋습니다. 따라서 a.ravel().argsort()[:4]np.argpartition(a.ravel(), range(4))[:4]으로 바꾸십시오.

샘플 실행 - 일반적인 경우에 대한

In [285]: a 
Out[285]: 
array([[ inf, 1., 3., 2., 1.], 
     [ inf, inf, 2., 3., 2.], 
     [ inf, inf, inf, 5., 4.], 
     [ inf, inf, inf, inf, 1.], 
     [ inf, inf, inf, inf, inf]]) 

In [286]: out 
Out[286]: [(0, 1, 1.0), (0, 4, 1.0), (3, 4, 1.0), (0, 3, 2.0)] 

-

R,C = np.triu_indices(a.shape[1],1) 
idx = a[R,C].argsort()[:4] 
r,c = R[idx], C[idx] 
out = zip(r,c,a[r,c]) 

샘플 실행 - 성능

In [351]: a 
Out[351]: 
array([[ 68., 67., 81., 23., 16.], 
     [ 84., 83., 20., 66., 48.], 
     [ 58., 72., 98., 63., 30.], 
     [ 61., 40., 1., 86., 22.], 
     [ 29., 95., 38., 22., 95.]]) 
In [352]: out 
Out[352]: [(0, 4, 16.0), (1, 2, 20.0), (3, 4, 22.0), (0, 3, 23.0)] 

, np.argpartition을 사용하는 것이 좋습니다. 따라서 a[R,C].argsort()[:4]np.argpartition(a[R,C], range(4))[:4]으로 대체하십시오.

0

뭔가 작동합니다

import numpy as np 
a = np.random.rand(4,4) 
tuples = [(ix,iy, a[ix,iy]) for ix, row in enumerate(a) for iy, i in enumerate(row)] 
sorted(tuples,key=lambda x: x[2])[:10] 

경우 귀하의 질문에서 K = 10 ([:10]). 당신은 단지 위쪽 삼각형이 목록의 이해에 조건을 추가 할 수있는 요소를 원하는 경우

: Inf 채워진 배열

a = np.random.rand(4,4) 
tuples = [(ix,iy, a[ix,iy]) for ix, row in enumerate(a) for iy, i in enumerate(row) if ix<=iy] 
sorted(tuples,key=lambda x: x[2]) 
0

np.array은()N 경우 나는 heapq 모듈의 .heapify ((*의 np.ndenumerate()와 함께)를 평평하게하고, 사용하여에서 N 가장 작은 값을 얻을 수)과 같이.smallest() 방법 :

#!python 
flattened = [(y,x) for x,y in np.ndenumerate(n)] 
# tuples reversed for natural sorting on values rather than co-ords 
heapq.heapify(flattened) 
results = heapq.nsmallest(4, flattened) 

그러나 이것은 여분의 메모리를 많이 사용하고 파이썬의 기본 목록에 NumPy와의 효율적인 배열에서 데이터와 좌표를 추출합니다. 따라서 파이썬에서 더 기본적으로 더 좋은 방법이있을 것입니다.

+0

나는 이것을 시도했지만 행렬이 거대한 이유는 루프 때문에 실제로 느리다. –

+0

정확하게 말했듯이, 따라서 나의 다른 제안, http://stackoverflow.com/a/6910715/149076 ... 병목 현상은 컴파일 된 확장 기능이다. 부분 정렬을위한 낸피. –