2017-04-13 1 views
7

StackOverflow에 몇 가지 질문을했지만 관련 답변을 찾을 수 없습니다. numpyndarray에서 최대 값의 인덱스를 가져 오려고합니다. This link은 동일하지만 1D 배열에 대해 설명합니다. 2D 배열 용 np.argsort은 행별로 요소 정렬을 수행했습니다.numpy 다차원 배열에서 최대 값의 인덱스를 얻는 방법

Note: array elements are not unique. 

입력 즉 : 또한

import numpy as np 
n = np.arange(9).reshape(3,3) 
>>> n 
array([[0, 1, 2], 
    [3, 4, 5], 
    [6, 7, 8]]) 
s = n.argsort() 
>>> s 
array([[0, 1, 2], 
    [0, 1, 2], 
    [0, 1, 2]], dtype=int32) 

,

import numpy as np 
n = np.arange(9).reshape(3,3) 
s = n.argsort(axis=None) 
>>>s 
array([0, 1, 2, 3, 4, 5, 6, 7, 8], dtype=int32) 

하지만 여기 배열 구성을 해방하고 상기 요소의 원래의 색인을 구속 할 수 없다.

아무 도움도받지 못했습니다. ndarrays에 대한 np.argpartitionnp.argsort와 접근 방법의

+0

은 당신이 대답을 원하십니까 nD 배열의 2D 배열 (n> 2) – Chris

답변

6

커플 - 우리가 argparition를 사용하는 방법을 k_largest_index_argpartition_v1k_largest_index_argpartition_v2 사이 argpartition

차이로 두 가지 버전에

def k_largest_index_argpartition_v1(a, k): 
    idx = np.argpartition(-a.ravel(),k)[:k] 
    return np.column_stack(np.unravel_index(idx, a.shape)) 

def k_largest_index_argpartition_v2(a, k): 
    idx = np.argpartition(a.ravel(),a.size-k)[-k:] 
    return np.column_stack(np.unravel_index(idx, a.shape)) 

def k_largest_index_argsort(a, k): 
    idx = np.argsort(a.ravel())[:-k-1:-1] 
    return np.column_stack(np.unravel_index(idx, a.shape)) 

토론이다. 첫 번째 버전에서는 입력 배열을 무효화하고 가장 작은 k 색인에 대한 색인을 얻으려면 argpartition을 사용하므로 가장 큰 k 색인을 얻는 반면 두 번째 버전에서는 가장 작은 색인을 얻는 반면에 가장 작은 색인은 가장 큰 나머지는 k 색인을 선택하십시오.

argpartition으로 여기에 언급할만한 가치가 있으며, 정렬 된 순서로 색인을 얻지는 못합니다. 정렬 된 순서가 필요한 경우 범위 배열을 post에서 설명한대로 np.argpartition으로 입력해야합니다.

샘플 실행 -

1) 2D의 경우 :

In [42]: a # 2D array 
Out[42]: 
array([[38, 14, 81, 50], 
     [17, 65, 60, 24], 
     [64, 73, 25, 95]]) 

In [43]: k_largest_index_argsort(a, k=2) 
Out[43]: 
array([[2, 3], 
     [0, 2]]) 

In [44]: k_largest_index_argsort(a, k=4) 
Out[44]: 
array([[2, 3], 
     [0, 2], 
     [2, 1], 
     [1, 1]]) 

In [66]: k_largest_index_argpartition_v1(a, k=4) 
Out[66]: 
array([[2, 1], # Notice the order is different 
     [2, 3], 
     [0, 2], 
     [1, 1]]) 

2) 3D 케이스 :

In [46]: a # 3D array 
Out[46]: 
array([[[20, 98, 27, 73], 
     [33, 78, 48, 59], 
     [28, 91, 64, 70]], 

     [[47, 34, 51, 19], 
     [73, 38, 63, 94], 
     [95, 25, 93, 64]]]) 

In [47]: k_largest_index_argsort(a, k=2) 
Out[47]: 
array([[0, 0, 1], 
     [1, 2, 0]]) 

런타임 테스트 -

In [56]: a = np.random.randint(0,99999999999999,(3000,4000)) 

In [57]: %timeit k_largest_index_argsort(a, k=10) 
1 loops, best of 3: 2.18 s per loop 

In [58]: %timeit k_largest_index_argpartition_v1(a, k=10) 
10 loops, best of 3: 178 ms per loop 

In [59]: %timeit k_largest_index_argpartition_v2(a, k=10) 
10 loops, best of 3: 128 ms per loop 
+0

이것은 효과가 있습니다. 감사합니다. –

+0

명확성을 위해, argpartition은 맨 위의'k'를 순서대로 제공하지 않으며, 처음 순서의 맨 위'k'만을 제공합니다. 'argsort'의 속도,'argsort'의 순서) 양쪽 모두의 장점을 최대한 살리는 방법은 파티션을 정렬하는 것입니다 :'idx2 = np.argsort (-a.ravel() [idx])'그리고 나서 'row, col = np.unravel.index (idx [idx2], a.shape)' –

+0

@ DanielForsman 그래, 그것에 대한 몇 가지 의견을 추가했습니다. – Divakar

관련 문제