numpy 배열에서 행 삭제


88

다음과 같은 배열이 있습니다.

ANOVAInputMatrixValuesArray = [[ 0.96488889, 0.73641667, 0.67521429, 0.592875, 
0.53172222], [ 0.78008333, 0.5938125, 0.481, 0.39883333, 0.]]

행 중 하나의 끝에 0 값이 있습니다. 모든 셀에서 0이 아닌 값을 포함하는 모든 행을 유지하면서 0이 포함 된 모든 행을 삭제하고 싶습니다.

그러나 배열은 채워질 때마다 다른 수의 행을 가지며 0은 매번 다른 행에 위치합니다.

다음 코드 줄을 사용하여 각 행에서 0이 아닌 요소의 수를 얻습니다.

NumNonzeroElementsInRows    = (ANOVAInputMatrixValuesArray != 0).sum(1)

위 배열의 경우 다음을 NumNonzeroElementsInRows포함합니다. [5 4]

5는 행 0의 가능한 모든 값이 0이 아님을 나타내고 4는 행 1의 가능한 값 중 하나가 0임을 나타냅니다.

따라서 다음 코드 줄을 사용하여 0 값이 포함 된 행을 찾아 삭제하려고합니다.

for q in range(len(NumNonzeroElementsInRows)):
    if NumNonzeroElementsInRows[q] < NumNonzeroElementsInRows.max():
        p.delete(ANOVAInputMatrixValuesArray, q, axis=0)

그러나 어떤 이유로이 코드는 많은 인쇄 명령을 수행하면 모든 변수가 코드로 이어지는 올바르게 채워지는 것처럼 보임에도 불구하고 아무것도 수행하지 않는 것 같습니다.

"0 값을 포함하는 모든 행을 삭제"하는 쉬운 방법이 있어야합니다.

누구든지 이것을 수행하기 위해 작성해야 할 코드를 보여줄 수 있습니까?

답변:


162

배열에서 행과 열을 삭제하는 가장 간단한 방법은 numpy.delete방법입니다.

다음 배열이 있다고 가정합니다 x.

x = array([[1,2,3],
        [4,5,6],
        [7,8,9]])

첫 번째 행을 삭제하려면 다음과 같이하십시오.

x = numpy.delete(x, (0), axis=0)

세 번째 열을 삭제하려면 다음과 같이하십시오.

x = numpy.delete(x,(2), axis=1)

따라서 0이있는 행의 인덱스를 찾아서 목록이나 튜플에 넣고 이것을 함수의 두 번째 인수로 전달할 수 있습니다.


감사! 나도 같은 문제가 있었는데 왜 단순히 전화 numpy.delete(x, index)가 안되는지 알 수 없었다 .
Antimony

6
(가) 있습니다 워드 프로세서) (삭제 NumPy와 예는 링크에서 제공되는 - 반환되는 새로운 배열 때문에 "종종 부울 마스크를 사용하는 것이 바람직하다"고 표시
arturomp

1
@arturomp이지만 마스크는 비파괴 적입니다. delete () 호출에 시간 / 메모리가 많이 소모됩니까?
Nathan

13

다음은 하나의 라이너입니다 (예, user333700과 비슷하지만 조금 더 간단합니다).

>>> import numpy as np
>>> arr = np.array([[ 0.96488889, 0.73641667, 0.67521429, 0.592875, 0.53172222], 
                [ 0.78008333, 0.5938125, 0.481, 0.39883333, 0.]])
>>> print arr[arr.all(1)]
array([[ 0.96488889,  0.73641667,  0.67521429,  0.592875  ,  0.53172222]])

그건 그렇고,이 방법은 큰 행렬의 마스크 배열 방법보다 훨씬 빠릅니다. 2048 x 5 행렬의 경우이 방법은 약 1000 배 더 빠릅니다.

그건 그렇고, user333700의 방법 (그의 의견에서)은 내 테스트에서 약간 더 빨랐지만 그 이유는 내 마음을 흔들어 놓았습니다.


3
"any"는 단락 될 수 있으며 첫 번째 실제 사례가 감지되는 즉시 중지 할 수 있으며 "all"은 모든 조건을 확인해야합니다. 따라서 (numpy에서 "~"는) 일반적으로 모든 것보다 빠릅니다.
Josef

4
@ user333700, 둘 다 다른 것들로 단락 될 수 있습니다. any첫 번째 실제 사례가 감지되면 단락이 true로 전환됩니다. all첫 번째 거짓 사례가 감지되면 단락이 거짓으로 전환됩니다. 이 경우, 쇼트는 무승부가되어야하지만, 엑스트라를하는 것은 제 생각에 느려질 것입니다.
Justin Peel

5

이것은 원래 접근 방식과 유사하며 unutbu의 답변 보다 적은 공간을 사용 하지만 느릴 것이라고 생각합니다.

>>> import numpy as np
>>> p = np.array([[1.5, 0], [1.4,1.5], [1.6, 0], [1.7, 1.8]])
>>> p
array([[ 1.5,  0. ],
       [ 1.4,  1.5],
       [ 1.6,  0. ],
       [ 1.7,  1.8]])
>>> nz = (p == 0).sum(1)
>>> q = p[nz == 0, :]
>>> q
array([[ 1.4,  1.5],
       [ 1.7,  1.8]])

그건 그렇고, 당신의 라인 p.delete()은 나를 위해 작동하지 않습니다- 속성 ndarray이 없습니다 .delete.


8
좀 더 간단합니다 : p [~ (p == 0) .any (1)] 또는 행에 대해 더 명시 적 : p [~ (p == 0) .any (1), :]
Josef

2

numpy는 똑같은 작업을 수행하는 간단한 함수를 제공합니다. 마스킹 된 배열 'a'가 있다고 가정하고 numpy.ma.compress_rows (a)를 호출하면 마스킹 된 값이 포함 된 행이 삭제됩니다. 이쪽이 훨씬 빠른 것 같아요 ...


1
import numpy as np 
arr = np.array([[ 0.96488889, 0.73641667, 0.67521429, 0.592875, 0.53172222],[ 0.78008333, 0.5938125, 0.481, 0.39883333, 0.]])
print(arr[np.where(arr != 0.)])

-1

이 질문에 답하기에는 너무 늦었지만 커뮤니티를 위해 제 의견을 공유하고 싶었습니다. 이 예에서는 행렬 'ANOVA'라고 부르겠습니다.이 행렬에서 5 번째 열에 만 0이있는 행을 제거하려고한다고 가정합니다.

indx = []
for i in range(len(ANOVA)):
    if int(ANOVA[i,4]) == int(0):
        indx.append(i)

ANOVA = [x for x in ANOVA if not x in indx]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.