두 가지 조건을 준수하기 위해 두 개의 numpy 배열 비교

Aug 18 2020

1과 0으로 구성된 A와 B라는 동일한 모양을 가진 두 개의 numpy 배열을 고려하십시오. 작은 예가 표시됩니다.

A = [[1 0 0 1]         B = [[0 0 0 0]
     [0 0 1 0]              [0 0 0 0]
     [0 0 0 0]              [1 1 0 0]
     [0 0 0 0]              [0 0 1 0]
     [0 0 1 1]]             [0 1 0 1]]

이제 다음과 같이 두 개의 부울 변수 test1test2에 값을 할당하려고 합니다.

test1 : A열에 1이 있고 SAME B열에 1이 정확히 1 또는 2의 행 차이가 있는 인스턴스가 하나 이상 있습니까? 그렇다면 test1 = True, 그렇지 않으면 False입니다.

위의 예에서 두 배열의 열 0에는 2 개의 행으로 떨어진 1이 있으므로 test1 = True입니다. (열 2에도 다른 인스턴스가 있지만 상관 없습니다. 하나의 인스턴스 만 필요합니다.)

test2 :의 1 개 값 AB모두 다른 배열 주소를 가지고 있습니까? 그렇다면 test2 = True이고 그렇지 않으면 False입니다.

위의 예에서 두 배열 모두가 [4,3] = 1이므로 test2 = False입니다.

이 작업을 수행하는 효율적인 방법을 찾기 위해 고군분투하고 있으며 도움을 주시면 감사하겠습니다.

답변

1 MadPhysicist Aug 18 2020 at 09:53

다음은 두 배열의 항목이 동일한 열에서 한 요소 떨어져 있는지 테스트하는 간단한 방법입니다 (한 방향으로 만).

(A[1:, :] * B[:-1, :]).any(axis=None)

그래서 당신은 할 수 있습니다

test1 = (A[1:, :] * B[:-1, :] + A[:-1, :] * B[1:, :]).any(axis=None) or (A[2:, :] * B[:-2, :] + A[:-2, :] * B[2:, :]).any(axis=None)

두 번째 테스트는 위치를 인덱스로 변환하고 함께 쌓고을 사용하여 np.unique중복 수를 계산 하여 수행 할 수 있습니다. 중복은 두 배열의 동일한 인덱스에서만 올 수 있습니다. 배열에는 중복 인덱스가 없기 때문입니다. flatnonzero대신 다음을 사용하여 계산 속도를 높일 수 있습니다 nonzero.

test2 = np.all(np.unique(np.concatenate((np.flatnonzero(A), np.flatnonzero(B))), return_counts=True)[1] == 1)

보다 효율적인 테스트는 np.intersect1d비슷한 방식으로 사용 됩니다.

test2 = not np.intersect1d(np.flatnonzero(A), np.flatnonzero(B)).size
1 Ehsan Aug 18 2020 at 08:14

masked_arrays를 사용할 수 있으며 두 번째 작업에는 다음을 수행 할 수 있습니다.

A_m = np.ma.masked_equal(A, 0)
B_m = np.ma.masked_equal(B, 0)

test2 = np.any((A_m==B_m).compressed())

첫 번째 작업을 수행하는 순진한 방법은 다음과 같습니다.

test1 = np.any((np.vstack((A_m[:-1],A_m[:-2],A_m[1:],A_m[2:]))==np.vstack((B_m[1:],B_m[2:],B_m[:-1],B_m[:-2]))).compressed())

산출:

True
True
ArundeepChohan Aug 18 2020 at 09:56

Test2의 경우 : 값 1에 대해 유사한 인덱스를 찾았는지 확인할 수 있습니다.

A =  np.array([[1, 0, 0, 1],[0, 0, 1, 0],[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 1, 1]])
B = np.array([[0, 0, 0, 0],[0, 0, 0, 0],[1, 1, 0, 0],[0, 0, 1, 0],[0, 1, 0, 1]])
print(len(np.intersect1d(np.flatnonzero(A==1),np.flatnonzero(B==1)))>0))