인덱스 목록을 사용하여 행당 특정 열 인덱스를 선택하는 NumPy
저는 NumPy 행렬의 행당 특정 열을 선택하는 데 어려움을 겪고 있습니다.
제가 다음과 같은 행렬을 가지고 있다고 가정합니다.X
:
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
저도 있습니다.list
호출할 모든 행당 열 인덱스 수Y
:
[1, 0, 2]
값을 가져와야 합니다.
[2]
[4]
[9]
대신에list
인덱스 포함Y
저는 또한 다음과 같은 모양의 행렬을 만들 수 있습니다.X
모든 열이 a인 경우bool
/int
필요한 열인지 여부를 나타내는 0-1 범위의 값입니다.
[0, 1, 0]
[1, 0, 0]
[0, 0, 1]
배열을 반복하고 필요한 열 값을 선택하면 이 작업을 수행할 수 있습니다.그러나 이는 빅 데이터 어레이에서 자주 실행되므로 최대한 빠르게 실행해야 합니다.
그래서 저는 더 나은 해결책이 있는지 궁금했습니다.
부울 배열이 있는 경우 다음과 같이 직접 선택할 수 있습니다.
>>> a = np.array([True, True, True, False, False])
>>> b = np.array([1,2,3,4,5])
>>> b[a]
array([1, 2, 3])
초기 예제와 함께 다음을 수행할 수 있습니다.
>>> a = np.array([[1,2,3], [4,5,6], [7,8,9]])
>>> b = np.array([[False,True,False],[True,False,False],[False,False,True]])
>>> a[b]
array([2, 4, 9])
다음을 추가할 수도 있습니다.arange
부울 어레이를 생성하는 방법과 YMMV 코드 모양에 따라 직접 선택할 수 있습니다.
>>> a = np.array([[1,2,3], [4,5,6], [7,8,9]])
>>> a[np.arange(len(a)), [1,0,2]]
array([2, 4, 9])
다음과 같은 작업을 수행할 수 있습니다.
In [7]: a = np.array([[1, 2, 3],
...: [4, 5, 6],
...: [7, 8, 9]])
In [8]: lst = [1, 0, 2]
In [9]: a[np.arange(len(a)), lst]
Out[9]: array([2, 4, 9])
다차원 배열 인덱싱에 대한 자세한 내용은 http://docs.scipy.org/doc/numpy/user/basics.indexing.html#indexing-multi-dimensional-arrays 을 참조하십시오. http://docs.scipy.org/doc/numpy/user/basics.indexing.html#indexing-multi-dimensional-arrays
최근.numpy
버전이 추가되었습니다.take_along_axis
(및put_along_axis
이 인덱싱을 깔끔하게 수행합니다.
In [101]: a = np.arange(1,10).reshape(3,3)
In [102]: b = np.array([1,0,2])
In [103]: np.take_along_axis(a, b[:,None], axis=1)
Out[103]:
array([[2],
[4],
[9]])
다음과 같은 방식으로 작동합니다.
In [104]: a[np.arange(3), b]
Out[104]: array([2, 4, 9])
하지만 축 핸들링이 다릅니다.그것은 특히 결과를 적용하는 것을 목표로 합니다.argsort
그리고.argmax
.
간단한 방법은 다음과 같습니다.
In [1]: a = np.array([[1, 2, 3],
...: [4, 5, 6],
...: [7, 8, 9]])
In [2]: y = [1, 0, 2] #list of indices we want to select from matrix 'a'
range(a.shape[0])
돌아올 것입니다array([0, 1, 2])
In [3]: a[range(a.shape[0]), y] #we're selecting y indices from every row
Out[3]: array([2, 4, 9])
반복기를 사용하여 수행할 수 있습니다.다음과 같이:
np.fromiter((row[index] for row, index in zip(X, Y)), dtype=int)
시간:
N = 1000
X = np.zeros(shape=(N, N))
Y = np.arange(N)
#@Aशwini चhaudhary
%timeit X[np.arange(len(X)), Y]
10000 loops, best of 3: 30.7 us per loop
#mine
%timeit np.fromiter((row[index] for row, index in zip(X, Y)), dtype=int)
1000 loops, best of 3: 1.15 ms per loop
#mine
%timeit np.diag(X.T[Y])
10 loops, best of 3: 20.8 ms per loop
take_along_axis를 사용하는 hpaulj의 답변은 허용된 답변이어야 합니다.
다음은 N-dim 인덱스 배열이 있는 파생 버전입니다.
>>> arr = np.arange(20).reshape((2,2,5))
>>> idx = np.array([[1,0],[2,4]])
>>> np.take_along_axis(arr, idx[...,None], axis=-1)
array([[[ 1],
[ 5]],
[[12],
[19]]])
선택 작업은 모양에 대해 잘 알지 못합니다.이것을 이용해서 가능한 벡터 값을 다듬었습니다.argmax
으로부터 결과가 나온histogram
포물선을 장착함으로써:
def interpol(arr):
i = np.argmax(arr, axis=-1)
a = lambda Δ: np.squeeze(np.take_along_axis(arr, i[...,None]+Δ, axis=-1), axis=-1)
frac = .5*(a(1) - a(-1)) / (2*a(0) - a(-1) - a(1)) # |frac| < 0.5
return i + frac
참고:squeeze
크기 1의 치수를 제거하여 동일한 모양을 만듭니다.i
그리고.frac
피크 위치의 정수 및 분수 부분.
저는 그것을 피하는 것이 가능하다고 꽤 확신합니다.lambda
그래도 보간 공식이 좋아 보일까요?
또 다른 영리한 방법은 먼저 배열을 전치한 후 색인화하는 것입니다.마지막으로, 대각선을 택하세요, 그것은 항상 옳은 답입니다.
X = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
Y = np.array([1, 0, 2, 2])
np.diag(X.T[Y])
단계별:
원본 배열:
>>> X
array([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12]])
>>> Y
array([1, 0, 2, 2])
올바른 색인화가 가능하도록 전치합니다.
>>> X.T
array([[ 1, 4, 7, 10],
[ 2, 5, 8, 11],
[ 3, 6, 9, 12]])
Y 순서로 행을 가져옵니다.
>>> X.T[Y]
array([[ 2, 5, 8, 11],
[ 1, 4, 7, 10],
[ 3, 6, 9, 12],
[ 3, 6, 9, 12]])
이제 대각선이 명확해집니다.
>>> np.diag(X.T[Y])
array([ 2, 4, 9, 12]
언급URL : https://stackoverflow.com/questions/23435782/numpy-selecting-specific-column-index-per-row-by-using-a-list-of-indexes
'programing' 카테고리의 다른 글
SQL 화학: 만들기 vs.세션 재사용 (0) | 2023.07.18 |
---|---|
준비된 파일의 Git 목록 (0) | 2023.07.18 |
줄의 왼쪽 부분을 제거하는 방법은 무엇입니까? (0) | 2023.07.18 |
요소에 대한 유형 스크립트에서 여러 CSS 스타일 속성을 설정하는 방법은 무엇입니까? (0) | 2023.07.18 |
코코아 포드 설치: 응답 없음 (0) | 2023.07.18 |