차원 정보 손실없이 Numpy 인덱스 슬라이스


100

numpy를 사용하고 있으며 차원 정보를 잃지 않고 행을 인덱싱하고 싶습니다.

import numpy as np
X = np.zeros((100,10))
X.shape        # >> (100, 10)
xslice = X[10,:]
xslice.shape   # >> (10,)  

이 예에서 xslice는 이제 1 차원이지만 (1,10)이되기를 원합니다. R에서는 X [10, :, drop = F]를 사용합니다. numpy에 비슷한 것이 있습니까? 나는 문서에서 그것을 찾을 수 없었고 비슷한 질문이 요구되는 것을 보지 못했습니다.

감사!

답변:


59

아마도 가장 쉬운 방법 x[None, 10, :]이거나 동등하게 (하지만 더 읽기 쉽습니다 ) x[np.newaxis, 10, :].

왜 이것이 기본값이 아닌지에 관해서는 개인적으로 단일 차원의 배열을 지속적으로 갖는 것이 매우 빠르게 성가신다는 것을 알았습니다. 나는 numpy 개발자가 같은 느낌을 받았다고 생각합니다.

또한 numpy는 브로드 캐스팅 배열을 매우 잘 처리하므로 일반적으로 슬라이스가 나온 배열의 차원을 유지할 이유가 거의 없습니다. 그랬다면 다음과 같은 것들이 있습니다.

a = np.zeros((100,100,10))
b = np.zeros(100,10)
a[0,:,:] = b

작동하지 않거나 구현하기가 훨씬 더 어려울 것입니다.

(또는 적어도 그것은 슬라이싱 할 때 차원 정보를 삭제하는 것에 대한 numpy dev의 추론에 대한 내 추측입니다)


6
@Lisa : x[None, 10]당신이 원하는 것을 할 것입니다.
naught101

예. None자르고있는 딤섬 옆에 s를 놓으십시오 .
Mad Physicist

1
예제는 할당에서 튜플에 대한 추가 대괄호가 누락되었습니다 b. 이어야합니다 b = np.zeros((100,10)).
Jerzy

2 개가 아닌 총 3 개의 인덱스를 사용하는 이유는 무엇입니까? 내 말은 X[10,None](예시로 코드 사용).
greenoldman

9
" 일반적으로 배열의 차원을 유지할 이유가 거의 없습니다. "... 확실히, 완전히, 그리고 행렬 곱셈 ( np.matmul()또는@ )을 완전히 망칠 것 입니다. 이것에 타버 렸습니다.
Jean-François Corbett

93

또 다른 해결책은

X[[10],:]

또는

I = array([10])
X[I,:]

인덱스 목록 (또는 배열)에 의해 인덱싱이 수행 될 때 배열의 차원 성이 유지됩니다. 치수를 유지하는 것과 짜내는 것 중에서 선택할 수 있기 때문에 좋습니다.


2
그러면 스토리지 데이터가 복사됩니다.
Per

항상 그런 것은 아닙니다. 참조 : x = np.array([[1,2,3,4]]) 당신은 다음과 슬라이스 경우 x[[0],[1,2]] 당신에게 한 차원 얻을 array([2, 3]) 슬라이스 간단하게 한 후 사용하는 열 또는 행 벡터가 최선의 선택시 내 의견은 np.reshape그래서 내 예제가 될 것이다,np.reshape(x[0,[1,2]],[1,2])
알렉산더

1
다른 사람들은 결국 세미콜론을 알고 있어야합니다. 중요 X[[10]]하며 X[10], 모양이 더 작아 질 것입니다. 유사하게, X[[10, 20]] == X[10, 20]모양도 작
벤 우스만

1
경고 : 이러한 방식의 인덱싱과 정수 인덱싱을 혼합하지 마십시오! 당신이 있다면 a모양 (10, 20, 30), 다음 a[0, :, [0]]모양 것 (1, 20),하지를 (20, 1)후자의 인덱스에 방송되기 때문에,에 a[[0], :, [0]]있는 자주는 아니지만 확실히 당신이 기대하는 무엇! 반면이 a[0, :, :1]당신을 줄 것이다 (20, 1)예상대로. 또한 단일 인덱스를 사용하는 이상한 경우에 대해서는 위의 주석을 참조하십시오. 전반적으로이 방법은 너무 많은 엣지 케이스를 가지고있는 것 같습니다.
Ben Usman

30

몇 가지 합리적인 해결책을 찾았습니다.

1) 사용 numpy.take(X,[10],0)

2)이 이상한 인덱싱 사용 X[10:11:, :]

이상적으로는 이것이 기본값이어야합니다. 왜 차원이 떨어지는 지 이해하지 못했습니다. 그러나 그것은 numpy에 대한 토론입니다 ...


2
'dimensions'는 Python 목록을 인덱싱 할 때 삭제 alist[0]되고 슬라이스 할 때 유지됩니다.
hpaulj

5
옵션 2 ( slice(n, n+1)인덱스 추출 로 쓸 수 있음 n)는 당연히 n 차원 케이스로 확장되는 유일한 답이기 때문에 허용되는 답이어야합니다.
norok2

옵션 2는 X[10:11, :]Python 3.7.5 에서처럼 작성 될 수있는 것 같습니다 (즉, 11 뒤에 추가 콜론없이)
Joe

7

내가 더 좋아하는 대안이 있습니다. 단일 숫자로 인덱싱하는 대신 범위로 인덱싱하십시오. 즉, X[10:11,:]. ( 10:1111은 포함되지 않음).

import numpy as np
X = np.zeros((100,10))
X.shape        # >> (100, 10)
xslice = X[10:11,:]
xslice.shape   # >> (1,10)

이를 통해 더 많은 차원으로도 쉽게 이해할 None수 있으며 어떤 인덱스를 사용할 축을 알아낼 필요도 없습니다 . 또한 더 그냥 배열 크기에 따라 추가 부기를 할 필요가 없습니다 i:i+1어떤을 위해 i당신이 정기적으로 인덱싱에 사용했을 것이라고.

b = np.ones((2, 3, 4))
b.shape # >> (2, 3, 4)
b[1:2,:,:].shape  # >> (1, 3, 4)
b[:, 2:3, :].shape .  # >> (2, 1, 4)


0

런타임에 길이가 1 일 수있는 배열로 인덱싱하는 경우 특히 짜증이납니다. 이 경우 다음이 있습니다 np.ix_.

some_array[np.ix_(row_index,column_index)]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.