NumPy는 다음을 통해 배열의 최대 값 인덱스를 얻는 방법을 제안합니다. np.argmax
.
비슷한 것을 원하지만 N
최대 값 의 색인을 반환 합니다.
I 배열이있는 경우 예를 들어 [1, 3, 2, 4, 5]
, function(array, n=3)
인덱스 반환 [4, 3, 1]
요소에 대응 [5, 4, 3]
.
답변
내가 생각해 낸 가장 간단한 방법은 다음과 같습니다.
In [1]: import numpy as np
In [2]: arr = np.array([1, 3, 2, 4, 5])
In [3]: arr.argsort()[-3:][::-1]
Out[3]: array([4, 3, 1])
여기에는 완전한 배열이 포함됩니다. numpy
부분 정렬을 수행하는 기본 제공 방법을 제공 하는지 궁금합니다 . 지금까지 나는 하나를 찾을 수 없었습니다.
이 솔루션이 너무 느리면 (특히 작은 경우 n
) Cython 에서 코드를 작성하는 것이 좋습니다.
답변
최신 NumPy 버전 (1.8 이상)에는이를 argpartition
위한 함수가 있습니다 . 네 가지 가장 큰 요소의 지수를 얻으려면
>>> a = np.array([9, 4, 4, 3, 3, 9, 0, 4, 6, 0])
>>> a
array([9, 4, 4, 3, 3, 9, 0, 4, 6, 0])
>>> ind = np.argpartition(a, -4)[-4:]
>>> ind
array([1, 5, 8, 0])
>>> a[ind]
array([4, 9, 6, 9])
와 달리이 argsort
함수는 최악의 경우 선형 시간으로 실행되지만 평가 결과에서 볼 수 있듯이 반환 된 인덱스는 정렬되지 않습니다 a[ind]
. 필요한 경우 나중에 정렬하십시오.
>>> ind[np.argsort(a[ind])]
array([1, 8, 5, 0])
이런 식으로 최상위 k 요소를 정렬 된 순서로 얻으려면 O ( n + k log k ) 시간이 걸립니다.
답변
더 간단하면서도 :
idx = (-arr).argsort()[:n]
여기서 n 은 최대 값 수입니다.
답변
사용하다:
>>> import heapq
>>> import numpy
>>> a = numpy.array([1, 3, 2, 4, 5])
>>> heapq.nlargest(3, range(len(a)), a.take)
[4, 3, 1]
일반 파이썬 목록의 경우 :
>>> a = [1, 3, 2, 4, 5]
>>> heapq.nlargest(3, range(len(a)), a.__getitem__)
[4, 3, 1]
Python 2를 사용 xrange
하는 경우 대신range
.
출처 : heapq — 힙 큐 알고리즘
답변
다차원 배열로 작업하는 경우 인덱스를 평평하게하고 풀어야합니다.
def largest_indices(ary, n):
"""Returns the n largest indices from a numpy array."""
flat = ary.flatten()
indices = np.argpartition(flat, -n)[-n:]
indices = indices[np.argsort(-flat[indices])]
return np.unravel_index(indices, ary.shape)
예를 들면 다음과 같습니다.
>>> xs = np.sin(np.arange(9)).reshape((3, 3))
>>> xs
array([[ 0. , 0.84147098, 0.90929743],
[ 0.14112001, -0.7568025 , -0.95892427],
[-0.2794155 , 0.6569866 , 0.98935825]])
>>> largest_indices(xs, 3)
(array([2, 0, 0]), array([2, 2, 1]))
>>> xs[largest_indices(xs, 3)]
array([ 0.98935825, 0.90929743, 0.84147098])
답변
사용할 수 있는 K 번째로 큰 요소 의 순서 에 신경 쓰지 않으면 argpartition
전체 정렬보다 성능이 우수합니다 argsort
.
K = 4 # We want the indices of the four largest values
a = np.array([0, 8, 0, 4, 5, 8, 8, 0, 4, 2])
np.argpartition(a,-K)[-K:]
array([4, 1, 5, 6])
크레딧은 이 질문으로 갑니다 .
몇 가지 테스트를 실행 했으며 배열의 크기와 K의 값이 증가함에 따라 argpartition
성능이 뛰어 argsort
납니다.
답변
다차원 배열의 경우 axis
키워드를 사용 하여 예상 축을 따라 분할을 적용 할 수 있습니다 .
# For a 2D array
indices = np.argpartition(arr, -N, axis=1)[:, -N:]
그리고 아이템을 잡기 위해 :
x = arr.shape[0]
arr[np.repeat(np.arange(x), N), indices.ravel()].reshape(x, N)
그러나 이렇게하면 정렬 된 결과가 반환되지 않습니다. 이 경우 np.argsort()
원하는 축을 따라 사용할 수 있습니다 .
indices = np.argsort(arr, axis=1)[:, -N:]
# Result
x = arr.shape[0]
arr[np.repeat(np.arange(x), N), indices.ravel()].reshape(x, N)
예를 들면 다음과 같습니다.
In [42]: a = np.random.randint(0, 20, (10, 10))
In [44]: a
Out[44]:
array([[ 7, 11, 12, 0, 2, 3, 4, 10, 6, 10],
[16, 16, 4, 3, 18, 5, 10, 4, 14, 9],
[ 2, 9, 15, 12, 18, 3, 13, 11, 5, 10],
[14, 0, 9, 11, 1, 4, 9, 19, 18, 12],
[ 0, 10, 5, 15, 9, 18, 5, 2, 16, 19],
[14, 19, 3, 11, 13, 11, 13, 11, 1, 14],
[ 7, 15, 18, 6, 5, 13, 1, 7, 9, 19],
[11, 17, 11, 16, 14, 3, 16, 1, 12, 19],
[ 2, 4, 14, 8, 6, 9, 14, 9, 1, 5],
[ 1, 10, 15, 0, 1, 9, 18, 2, 2, 12]])
In [45]: np.argpartition(a, np.argmin(a, axis=0))[:, 1:] # 1 is because the first item is the minimum one.
Out[45]:
array([[4, 5, 6, 8, 0, 7, 9, 1, 2],
[2, 7, 5, 9, 6, 8, 1, 0, 4],
[5, 8, 1, 9, 7, 3, 6, 2, 4],
[4, 5, 2, 6, 3, 9, 0, 8, 7],
[7, 2, 6, 4, 1, 3, 8, 5, 9],
[2, 3, 5, 7, 6, 4, 0, 9, 1],
[4, 3, 0, 7, 8, 5, 1, 2, 9],
[5, 2, 0, 8, 4, 6, 3, 1, 9],
[0, 1, 9, 4, 3, 7, 5, 2, 6],
[0, 4, 7, 8, 5, 1, 9, 2, 6]])
In [46]: np.argpartition(a, np.argmin(a, axis=0))[:, -3:]
Out[46]:
array([[9, 1, 2],
[1, 0, 4],
[6, 2, 4],
[0, 8, 7],
[8, 5, 9],
[0, 9, 1],
[1, 2, 9],
[3, 1, 9],
[5, 2, 6],
[9, 2, 6]])
In [89]: a[np.repeat(np.arange(x), 3), ind.ravel()].reshape(x, 3)
Out[89]:
array([[10, 11, 12],
[16, 16, 18],
[13, 15, 18],
[14, 18, 19],
[16, 18, 19],
[14, 14, 19],
[15, 18, 19],
[16, 17, 19],
[ 9, 14, 14],
[12, 15, 18]])
