NumPy 2d 배열의 슬라이싱 또는 nxn 배열(n>m)에서 mxm 하위 매트릭스를 추출하는 방법은 무엇입니까?
NumPinxn 배열을 슬라이스하고 싶습니다.해당 배열의 행과 열을 임의로 선택하여 추출(예: 행/열 수에 패턴이 없음)하여 새 mxm 배열로 만듭니다.이 예에서는 어레이가 4x4이고 여기서 2x2 어레이를 추출하려고 합니다.
다음은 당사의 어레이입니다.
from numpy import *
x = range(16)
x = reshape(x,(4,4))
print x
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
제거할 선과 열이 동일합니다.가장 쉬운 경우는 시작 부분이나 끝 부분에 있는 2x2 하위 매트릭스를 추출하려는 경우입니다. 예:
In [33]: x[0:2,0:2]
Out[33]:
array([[0, 1],
[4, 5]])
In [34]: x[2:,2:]
Out[34]:
array([[10, 11],
[14, 15]])
그러나 행/열이 혼합된 다른 항목을 제거해야 하는 경우에는 어떻게 해야 합니까?첫 번째와 세 번째 행/행을 제거하여 하위 매트릭스를 추출해야 하는 경우[[5,7],[13,15]]
임의의 행/라인 구성이 있을 수 있습니다.행과 열 모두에 대해 배열/색인 목록을 사용하여 어레이를 인덱싱하기만 하면 된다는 내용을 어디선가 읽었지만, 작동하지 않는 것 같습니다.
In [35]: x[[1,3],[1,3]]
Out[35]: array([ 5, 15])
한 가지 방법을 찾았어요. 바로 다음과 같습니다.
In [61]: x[[1,3]][:,[1,3]]
Out[61]:
array([[ 5, 7],
[13, 15]])
이것에 대한 첫 번째 문제는 제가 그것을 견딜 수는 있지만 읽기 어렵다는 것입니다.누군가 더 좋은 해결책이 있다면 꼭 듣고 싶습니다.
또한 포럼에서 읽은 바에 따르면 어레이가 포함된 인덱싱 어레이는 NumPy가 원하는 어레이의 복사본을 만들 수 있으므로 대규모 어레이로 처리할 때 문제가 될 수 있습니다.왜 그럴까요? / 이 메커니즘은 어떻게 작동하나요?
이 질문에 답하려면 Numpy에서 다차원 배열 인덱싱이 어떻게 작동하는지 살펴봐야 합니다.먼저 당신이 그 배열을 가지고 있다고 가정해 보겠습니다.x
당신의 질문에서.에 입니다.x
0까지의 의 오름차순 합니다.한 요소에 액세스할 경우 다음과 같이 말합니다.x[i,j]
NumPy는 버퍼의 시작을 기준으로 이 요소의 메모리 위치를 파악해야 합니다.으로 계산함으로써 이루어집니다.i*x.shape[1]+j
실제 메모리 오프셋을 얻기 위해 int 크기를 곱합니다.
다음과 같이 기본적인 슬라이싱으로 서브어레이를 추출하면y = x[0:2,0:2]
된 객체는 기본 를 결과개버공유다니합과 합니다.x
당신이 하만당접어될떻까요게면속하지신이에 ?y[i,j]
는 NumPy를 수 .i*y.shape[1]+j
가 오에속데때문프계산에 y
메모리가 연속적이지 않습니다.
NumPy는 약진을 도입하여 이 문제를 해결합니다.액세스를 위한 메모리 오프셋을 계산할 때x[i,j]
은 실로계된것은입니다.i*x.strides[0]+j*x.strides[1]
int의 하고 있습니다int는 int의 크기에 대한 인자입니다.)
x.strides
(16, 4)
때y
위와 같이 추출되며, NumPy는 새 버퍼를 만들지 않지만 동일한 버퍼를 참조하는 새 어레이 개체를 만듭니다(그렇지 않으면).y
와 동등할 것입니다.x
새 것입니다.) 그러면새개모달양다니라집이의체배열▁.다니▁will달집라▁object▁then.x
그리고 버퍼에 다른 시작 오프셋이 있을 수 있지만, 진전을 공유할 것입니다.x
이 으)로 표시됩니다.
y.shape
(2,2)
y.strides
(16, 4)
오프셋을 합니다.y[i,j]
정확한 결과를 얻을 수 있습니다.
하지만 는 NumPy와 같은 요?z=x[[1,3]]
원래 버퍼가 다음에 사용되는 경우에는 단계 메커니즘에서 올바른 인덱싱을 허용하지 않습니다.z
NumPy는 이론적으로 보폭보다 더 정교한 메커니즘을 추가할 수 있지만, 이는 요소 액세스를 상대적으로 비싸게 만들어 배열의 전체 아이디어를 무시합니다.게다가, 뷰는 더 이상 정말 가벼운 물체가 아닙니다.
이에 대한 자세한 내용은 인덱싱에 대한 NumPy 설명서에 나와 있습니다.
아, 그리고 당신의 실제 질문에 대해 거의 잊어버렸습니다.다음은 여러 목록이 포함된 인덱싱이 예상대로 작동하도록 하는 방법입니다.
x[[[1],[3]],[1,3]]
인덱스 배열이 공통 모양으로 브로드캐스트되기 때문입니다.물론 이 예에서는 기본적인 슬라이싱도 사용할 수 있습니다.
x[1::2, 1::2]
언급했듯이, 스이언급이듯했벤,이▁as,x[[[0],[2]],[1,3]]
1및 3 하는 0 및 2하며, 1 및 3 는 0 및 2 합 2 니 다 반x[[0,2],[1,3]]
배열에서 x[0,1] 및 x[2,3] 값을 반환합니다.
제가 처음으로 제시한 예시를 수행하는 데 도움이 되는 기능이 있습니다.numpy.ix_
첫 번째 예와 동일한 작업을 수행할 수 있습니다.x[numpy.ix_([0,2],[1,3])]
이렇게 하면 추가 대괄호를 모두 입력하지 않아도 됩니다.
나는 그렇게 생각하지 않는다.x[[1,3]][:,[1,3]]
거의 읽을 수 없습니다.당신의 의도를 더 명확히 하고 싶다면, 당신은 다음을 할 수 있습니다.
a[[1,3],:][:,[1,3]]
저는 슬라이싱 전문가는 아니지만 일반적으로 배열로 슬라이스하려고 시도하고 값이 연속적인 경우 스트라이드 값이 변경되는 뷰를 다시 얻을 수 있습니다.
예를 들어 입력 33과 34에서는 2x2 배열을 사용하지만 스트라이드는 4입니다.따라서 다음 행을 인덱싱할 때 포인터가 메모리의 올바른 위치로 이동합니다.
분명히, 이 메커니즘은 일련의 지수의 경우에 잘 적용되지 않습니다.따라서, numpy는 복사를 해야 할 것입니다.결국, 많은 다른 행렬 산술 함수는 크기, 스트라이드 및 연속 메모리 할당에 의존합니다.
다른 모든 행과 다른 열을 건너뛰려면 기본 슬라이싱을 사용하여 다음 작업을 수행할 수 있습니다.
In [49]: x=np.arange(16).reshape((4,4))
In [50]: x[1:4:2,1:4:2]
Out[50]:
array([[ 5, 7],
[13, 15]])
그러면 배열의 복사본이 아닌 보기가 반환됩니다.
In [51]: y=x[1:4:2,1:4:2]
In [52]: y[0,0]=100
In [53]: x # <---- Notice x[1,1] has changed
Out[53]:
array([[ 0, 1, 2, 3],
[ 4, 100, 6, 7],
[ 8, 9, 10, 11],
[ 12, 13, 14, 15]])
하는 동안에z=x[(1,3),:][:,(1,3)]
고급 인덱싱을 사용하여 복사본을 반환합니다.
In [58]: x=np.arange(16).reshape((4,4))
In [59]: z=x[(1,3),:][:,(1,3)]
In [60]: z
Out[60]:
array([[ 5, 7],
[13, 15]])
In [61]: z[0,0]=0
:x
변경되지 않음:
In [62]: x
Out[62]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
임의의 행과 열을 선택하려면 기본 슬라이싱을 사용할 수 없습니다.인덱싱을 . 예를 들어, " 급인덱을합다니야사"와 같은 x[rows,:][:,columns]
서, 디에어rows
그리고.columns
시입니다 ▁this다니. 이것은 입니다.물론 이것은 보기가 아니라 원래 배열의 복사본을 제공할 것입니다.numpy 배열은 연속적인 메모리를 사용하기 때문에(일정한 단계로), 임의의 행과 열로 뷰를 생성할 수 없습니다(일정하지 않은 단계가 필요하므로).
numpy를 사용하면 인덱스의 각 구성 요소에 대한 슬라이스를 전달할 수 있습니다. 따라서,x[0:2,0:2]
위 작품들의 예시.
열이나 행을 고르게 건너뛰려면 세 가지 성분(예: 시작, 중지, 단계)으로 슬라이스를 전달할 수 있습니다.
위의 예에 대해서도 마찬가지입니다.
>>> x[1:4:2, 1:4:2]
array([[ 5, 7],
[13, 15]])
기본적으로 첫 번째 차원에서 슬라이스하고 인덱스 1에서 시작하며 인덱스가 4 이상일 때 중지하고 각 패스에서 인덱스에 2를 추가합니다.두 번째 차원도 마찬가지입니다.다시 말하지만, 이것은 일정한 단계에서만 작동합니다.
내부적으로 상당히 다른 것을 해야 하는 구문 - 무엇.x[[1,3]][:,[1,3]]
실제로는 원래 배열에서 1행과 3행만 포함하는 새 배열을 만듭니다(이를 통해 수행됨).x[[1,3]]
part를 선택한 -array.part의 하여 세 배열을 함)을 합니다.
저도 비슷한 질문이 있습니다. 가장 피톤체적인 방식으로 하위 배열과 배열로 글을 쓰는 것입니다. 파이썬 2.
귀하의 사례에 대한 이전 게시물의 솔루션에 따르면 솔루션은 다음과 같습니다.
columns_to_keep = [1,3]
rows_to_keep = [1,3]
ix_:를 사용한 A:
x[np.ix_(rows_to_keep, columns_to_keep)]
즉,
array([[ 5, 7],
[13, 15]])
이것이 얼마나 효율적인지는 모르겠지만 범위()를 사용하여 양쪽 축에서 슬라이스할 수 있습니다.
x=np.arange(16).reshape((4,4))
x[range(1,3), :][:,range(1,3)]
언급URL : https://stackoverflow.com/questions/4257394/slicing-of-a-numpy-2d-array-or-how-do-i-extract-an-mxm-submatrix-from-an-nxn-ar
'programing' 카테고리의 다른 글
zshon mac에서 Git 탭 완료가 작동하지 않습니다. (0) | 2023.07.01 |
---|---|
결과를 나누기 위한 SQL의 십진수 값 (0) | 2023.07.01 |
Mongo 오류:이 MongoDB 배포는 재시도 가능한 쓰기를 지원하지 않습니다.연결 문자열에 retryWrites=false를 추가하십시오. (0) | 2023.07.01 |
정확히 무엇을 잘라내나요(날짜, 'IW')? (0) | 2023.07.01 |
테스트 목적으로 개인 plsql 절차에 액세스할 수 있는 방법이 있습니까? (0) | 2023.07.01 |