배열에 있는 항목의 첫 번째 인덱스를 반환하는 NumPy 함수가 있나요?

StackOverflow https://stackoverflow.com/questions/432112

  •  08-07-2019
  •  | 
  •  

문제

나는 Python 목록이 어떤 것의 첫 번째 색인을 반환하는 방법이 있다는 것을 알고 있습니다.

>>> l = [1, 2, 3]
>>> l.index(2)
1

NumPy 배열에 그런 것이 있습니까?

도움이 되었습니까?

해결책

예, Numpy Array가 주어진 답이 있습니다. array, 및 값, item, 검색하려면 :

itemindex = numpy.where(array==item)

결과는 먼저 모든 행 지수를 가진 튜플, 모든 열 인덱스가 있습니다.

예를 들어, 배열이 두 차원이고 두 위치에 항목이 포함 된 경우

array[itemindex[0][0]][itemindex[1][0]]

당신의 항목과 같을 것입니다

array[itemindex[0][1]][itemindex[1][1]]

Numpy. 어디서

다른 팁

첫 번째 발생 색인이 필요한 경우 단 하나의 값, 당신이 사용할 수있는 nonzero (또는 where,이 경우 같은 것들) : :

>>> t = array([1, 1, 1, 2, 2, 3, 8, 3, 8, 8])
>>> nonzero(t == 8)
(array([6, 8, 9]),)
>>> nonzero(t == 8)[0][0]
6

각각의 첫 번째 색인이 필요한 경우 많은 가치, 당신은 분명히 위와 동일하게 반복적으로 동일하게 할 수 있지만, 더 빠를 수있는 트릭이 있습니다. 다음은 각각의 첫 번째 요소의 지수를 찾습니다. 후속:

>>> nonzero(r_[1, diff(t)[:-1]])
(array([0, 3, 5, 6, 7, 8]),)

3 초의 후속 시퀀스와 8 초의 후속 시퀀스의 시작을 발견합니다.

[1, 1, 1, 2, 2, 3, 8, 3, 8, 8]

따라서 첫 번째를 찾는 것과 약간 다릅니다 발생 각 값의. 프로그램에서 정렬 된 버전으로 작업 할 수 있습니다. t 원하는 것을 얻으려면 :

>>> st = sorted(t)
>>> nonzero(r_[1, diff(st)[:-1]])
(array([0, 3, 5, 7]),)

Numpy 배열을 공중에서 목록으로 변환하고 색인을 얻을 수도 있습니다. 예를 들어,

l = [1,2,3,4,5] # Python list
a = numpy.array(l) # NumPy array
i = a.tolist().index(2) # i will return index of 2
print i

1 인쇄됩니다.

이것을 다른 것으로 인덱스로 사용하려면 배열이 방송 가능한 경우 부울 지수를 사용할 수 있습니다. 명시 적 지수가 필요하지 않습니다. 이를 수행하는 가장 간단한 방법은 단순히 진실 값을 기반으로 색인하는 것입니다.

other_array[first_array == item]

부울 운영이 작동합니다.

a = numpy.arange(100)
other_array[first_array > 50]

0이 아닌 방법은 부울을 취합니다.

index = numpy.nonzero(first_array == item)[0][0]

두 개의 0은 인덱스의 튜플 (First_Array가 1D라고 가정하고 인덱스 배열에서 첫 번째 항목을위한 것입니다.

매우 성능이 좋고 편리한 기능을 추가하기만 하면 됩니다. 기반으로 한 대안 np.ndenumerate 첫 번째 색인을 찾으려면 다음을 수행하십시오.

from numba import njit
import numpy as np

@njit
def index(array, item):
    for idx, val in np.ndenumerate(array):
        if val == item:
            return idx
    # If no item was found return None, other return types might be a problem due to
    # numbas type inference.

이것은 꽤 빠르고 다차원 배열을 자연스럽게 다룹니다.:

>>> arr1 = np.ones((100, 100, 100))
>>> arr1[2, 2, 2] = 2

>>> index(arr1, 2)
(2, 2, 2)

>>> arr2 = np.ones(20)
>>> arr2[5] = 2

>>> index(arr2, 2)
(5,)

이것은 될 수있다 훨씬 더 빨리 (작업이 단락되기 때문에) 다음을 사용하는 어떤 접근 방식보다 np.where 또는 np.nonzero.


하지만 np.argwhere 거래할 수도 있다 우아하게 다차원 배열 사용(수동으로 튜플로 캐스팅해야 함) 그리고 단락되지는 않았지만 일치하는 항목이 없으면 실패합니다.

>>> tuple(np.argwhere(arr1 == 2)[0])
(2, 2, 2)
>>> tuple(np.argwhere(arr2 == 2)[0])
(5,)

l.index(x) 가장 작은 것을 반환합니다 그렇게 목록에서 X의 첫 번째 발생 색인입니다.

하나는 안전하게 가정 할 수 있습니다 index() Python의 기능은 첫 번째 경기를 찾은 후 중지되도록 구현되며 최적의 평균 성능이 발생합니다.

Numpy 배열에서 첫 경기 후 중지 된 요소를 찾으려면 반복기를 사용하십시오 (ndenumerate).

In [67]: l=range(100)

In [68]: l.index(2)
Out[68]: 2

Numpy Array :

In [69]: a = np.arange(100)

In [70]: next((idx for idx, val in np.ndenumerate(a) if val==2))
Out[70]: (2L,)

두 방법 모두에 유의하십시오 index() 그리고 next 요소를 찾을 수없는 경우 오류를 반환하십시오. 와 함께 next, 두 번째 인수를 사용하여 요소를 찾을 수없는 경우 특별 값을 반환 할 수 있습니다.

In [77]: next((idx for idx, val in np.ndenumerate(a) if val==400),None)

Numpy에는 다른 기능이 있습니다 (argmax, where, 그리고 nonzero) 배열에서 요소를 찾는 데 사용될 수 있지만 모두 찾는 전체 배열을 통과하는 단점이 있습니다. 모두 따라서 첫 번째 요소를 찾는 데 최적화되지 않습니다. 또한 주목하십시오 where 그리고 nonzero 반환 배열이므로 인덱스를 얻으려면 첫 번째 요소를 선택해야합니다.

In [71]: np.argmax(a==2)
Out[71]: 2

In [72]: np.where(a==2)
Out[72]: (array([2], dtype=int64),)

In [73]: np.nonzero(a==2)
Out[73]: (array([2], dtype=int64),)

시간 비교

큰 배열에 대해 반복기를 사용하는 솔루션이 더 빠릅니다. 검색 된 항목이 배열의 시작 부분에있을 때 (사용 %timeit Ipython 쉘에서) :

In [285]: a = np.arange(100000)

In [286]: %timeit next((idx for idx, val in np.ndenumerate(a) if val==0))
100000 loops, best of 3: 17.6 µs per loop

In [287]: %timeit np.argmax(a==0)
1000 loops, best of 3: 254 µs per loop

In [288]: %timeit np.where(a==0)[0][0]
1000 loops, best of 3: 314 µs per loop

이것은 열린 것입니다 Numpy Github 문제.

또한보십시오: Numpy : 첫 번째 가치 지수를 빠르게 찾으십시오

모든 기준에 따라 색인하려면 다음과 같은 것과 같은 것입니다.

In [1]: from numpy import *
In [2]: x = arange(125).reshape((5,5,5))
In [3]: y = indices(x.shape)
In [4]: locs = y[:,x >= 120] # put whatever you want in place of x >= 120
In [5]: pts = hsplit(locs, len(locs[0]))
In [6]: for pt in pts:
   .....:         print(', '.join(str(p[0]) for p in pt))
4, 4, 0
4, 4, 1
4, 4, 2
4, 4, 3
4, 4, 4

그리고 여기에 List.Index ()가하는 일을 수행하는 빠른 기능이 있습니다. 찾을 수없는 경우 예외를 제외하고는 제외합니다. 조심하십시오 - 이것은 아마도 큰 배열에서 매우 느립니다. 메소드로 사용하려면 원숭이 패치를 배열로 만들 수 있습니다.

def ndindex(ndarray, item):
    if len(ndarray.shape) == 1:
        try:
            return [ndarray.tolist().index(item)]
        except:
            pass
    else:
        for i, subarray in enumerate(ndarray):
            try:
                return [i] + ndindex(subarray, item)
            except:
                pass

In [1]: ndindex(x, 103)
Out[1]: [4, 0, 3]

1D 배열의 경우 추천합니다 np.flatnonzero(array == value)[0], 이것은 둘 다에 해당합니다 np.nonzero(array == value)[0][0] 그리고 np.where(array == value)[0][0] 그러나 1 요소 튜플을 무너 뜨리는 추악함을 피하십시오.

Numpy에는이를 달성하기 위해 함께 모일 수있는 많은 작업이 있습니다. 이것은 항목과 동일한 요소의 지수를 반환합니다.

numpy.nonzero(array - item)

그런 다음 목록의 첫 번째 요소를 사용하여 단일 요소를 얻을 수 있습니다.

1 차원의 경우 정렬 배열, 사용하기가 훨씬 더 단순하고 효율적인 O (log (n))입니다. numpy.searchsorted Numpy Integer (위치)를 반환합니다. 예를 들어,

arr = np.array([1, 1, 1, 2, 3, 3, 4])
i = np.searchsorted(arr, 3)

배열이 이미 정렬되었는지 확인하십시오

또한 검색 된 인덱스가 실제로 검색 된 요소를 포함하는지 확인하십시오. 검색어의 주요 목표는 순서를 유지하기 위해 요소를 삽입 해야하는 지수를 찾는 것이므로.

if arr[i] == 3:
    print("present")
else:
    print("not present")

np.where()에서 첫 번째 요소를 선택하는 대신 다음과 같이 열거형과 함께 생성기 표현식을 사용하는 것입니다.

>>> import numpy as np
>>> x = np.arange(100)   # x = array([0, 1, 2, 3, ... 99])
>>> next(i for i, x_i in enumerate(x) if x_i == 2)
2

2차원 배열의 경우 다음을 수행합니다.

>>> x = np.arange(100).reshape(10,10)   # x = array([[0, 1, 2,... 9], [10,..19],])
>>> next((i,j) for i, x_i in enumerate(x) 
...            for j, x_ij in enumerate(x_i) if x_ij == 2)
(0, 2)

이 접근 방식의 장점은 첫 번째 일치 항목이 발견된 후 배열 요소 검사를 중지하는 반면 np.where는 모든 요소 일치 항목을 확인한다는 것입니다.배열 초기에 일치 항목이 있으면 생성기 표현식이 더 빨라집니다.

그만큼 numpy_indexed 패키지 (면책 조항, 나는 저자입니다)는 numpy.ndarray에 대한 목록의 벡터화 된 등가물을 포함합니다. 그건:

sequence_of_arrays = [[0, 1], [1, 2], [-5, 0]]
arrays_to_query = [[-5, 0], [1, 0]]

import numpy_indexed as npi
idx = npi.indices(sequence_of_arrays, arrays_to_query, missing=-1)
print(idx)   # [2, -1]

이 솔루션은 성능을 벡터화하고 Ndarray로 일반화하며 결 측값을 다루는 다양한 방법을 가지고 있습니다.

메모:이것은 Python 2.7 버전용입니다.

문제를 해결하기 위해 람다 함수를 사용할 수 있습니다. NumPy 배열과 목록 모두에서 작동합니다.

your_list = [11, 22, 23, 44, 55]
result = filter(lambda x:your_list[x]>30, range(len(your_list)))
#result: [3, 4]

import numpy as np
your_numpy_array = np.array([11, 22, 23, 44, 55])
result = filter(lambda x:your_numpy_array [x]>30, range(len(your_list)))
#result: [3, 4]

그리고 당신은 사용할 수 있습니다

result[0]

필터링된 요소의 첫 번째 인덱스를 가져옵니다.

Python 3.6의 경우 다음을 사용하십시오.

list(result)

대신에

result
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top