2017-05-10 1 views
3

나는 bool 배열 A와 B를 가지고 있고 C를 얻고 싶다. C는 A와 B의 논리 AND와 같지만 인덱스를 맞추는 데 약간의 흔들림이있다. 즉, 논리 AND는 A [r, c] AND B [r, c]를 수행 할 것입니다. 그러나 내가 원하는 것은 A [r +/- 1, c +/- 1] AND B [r +/- 1 , c +/- 1]. 모든 인덱스를 반복하지 않고 이상적으로이를 수행 할 수있는 좋은 방법이 있습니까?Numpy 논리적이고

>>> import numpy as np 
>>> A 
np.ndarray([[True, False, False, True], 
      [False, False, False, False], 
      [False, False, True, False], 
      [False, False, False, False]) 
>>> B 
np.ndarray([[False, True, False, False], 
      [False, False, False, False], 
      [True, True, True, False], 
      [False, False, False, False]) 
>>> np.logical_and(A, B) # only (2,2) is True 
np.ndarray([[False, False, False, False], 
      [False, False, False, False], 
      [False, False, True, False], 
      [False, False, False, False]) 
>>> C # (0,0), (1,0), and (2,1) also become True 
np.ndarray([[True, False, False, False], 
      [True, False, False, False], 
      [False, True, True, False], 
      [False, False, False, False]) 
+1

내가 중간 배열 AA 및 그 항목입니다 OR (A [R BB를 만들 것이다 +/- 1, c +/- 1]) 그리고 B에 대한 idem. 그러면 나는 논리와 AA와 BB 사이를 계산할 것이다. 이것은 여전히 ​​A와 B – fonfonx

+2

을 반복하거나 루프를 필요로하지 않지만 메모리가 비싸다. A에서 8 개의 쉬프트 된 배열을 만들 수 있으며 (B에서 모든 방향으로 +1 또는 -1) 그리고 모든 A 배열의 OR을 계산할 수있다. 모든 B 배열의 OR과 마지막으로이 중간 결과 간의 AND – fonfonx

+0

흠, 아마 B의 값에 A의 해당 섹션을 넣을 수 있습니까? – AetherUnbound

답변

1

, A [R +/- 1, C +/- 1] 및 B [R +/- 1 ]는 @AetherUnbound가 재현 한대로 다음 결과를 생성합니다. 이 원하는 출력 일 경우

[[ True True True False] 
[ True True True True] 
[False True True True] 
[False True True True]] 

, 우리는 A 및 B에 컨볼 루션 연산을 사용하여 최종 논리를 수행하고있다.

솔루션 다른 댓글이 지적한 것처럼

from scipy import ndimage 
#define a convolution filter with size 3*3 
f = np.full((3,3),True, dtype=bool) 

#Convolve A and B using a 3*3 filter and then do a logical and in the end. 
np.logical_and(ndimage.convolve(A,f,mode='constant', cval=False),ndimage.convolve(B,f,mode='constant', cval=False)) 
Out[766]: 
array([[ True, True, True, False], 
     [ True, True, True, True], 
     [False, True, True, True], 
     [False, True, True, True]], dtype=bool) 
+0

니스!나는 회선이 작동 할 것이라고 생각했다. 직접 구현하는 방법을 모르겠다. – AetherUnbound

+0

좋은 생각! 그리고 네, 문제 (+/- 두 배열에서) specced이 올바른 대답입니다. 고마워요 :) – BoltzmannBrain

+0

당신은 오신 것을 환영합니다. 기쁜 데 도움이되었습니다. – Allen

0

다음은 잠재적 인 해결책 중 하나입니다. 이것은 A 주위에 3x3 정사각형에 True이 있는지 확인하고 B에 대해서도 동일하게 수행합니다. 둘 다 True이면 해당 색인도 True입니다. 그것은 당신이 원하는 결과물을주지는 못하지만, 그것을 성취하기 위해 더 많은 설명이 필요합니다.

import numpy as np 

A = np.array([[True, False, False, True], [False, False, False, False], [False, False, True, False], [False, False, False, False]]) 

B = np.array([[False, True, False, False], [False, False, False, False], [True, True, True, False], [False, False, False, False]]) 

def and3x3(arr, x, y): 
    subarr = arr[max(0, x-1):x+2, max(0, y-1):y+2] 
    return np.any(subarr) 

C = np.zeros_like(B) 

for a in range(A.shape[0]): 
    for b in range(A.shape[1]): 
     t1 = and3x3(A, a, b) 
     t2 = and3x3(B, a, b) 
     C[a, b] = t1 * t2 

print(C) 

출력 : +/- 1 C I 올바르게 이해하면

[[ True True True False] 
[ True True True True] 
[False True True True] 
[False True True True]] 
1

은, 당신이 가지고있는 표기는 배열이 중복의 2 요소 반경있을 것입니다 나타냅니다. 당신은 중복의 한 요소 반경을하려는 대신하는 경우,이 시도 :

import numpy as np 

A=np.array([[True, False, False, True], 
      [False, False, False, False], 
      [False, False, True, False], 
      [False, False, False, False]]) 

B=np.array([[False, True, False, False], 
      [False, False, False, False], 
      [True, True, True, False], 
      [False, False, False, False]]) 

def conv(mat): 
    mat_pad=np.pad(mat,1,'constant') 
    return mat+.5*(np.roll(mat_pad,1,0)[1:-1,1:-1]+np.roll(mat_pad,-1,0)[1:-1,1:-1]+np.roll(mat_pad,1,1)[1:-1,1:-1]+np.roll(mat_pad,-1,1)[1:-1,1:-1]) 


C=conv(A)*conv(B)>=.5 
print(C) 

이 접근 반환 :

array([[ True, True, False, False], 
     [False, False, False, False], 
     [False, True, True, False], 
     [False, False, False, False]], dtype=bool) 
관련 문제