2012-11-19 2 views
3

패키지 scipy에는 이진 구조 (taxicab (2,1) 또는 체스 보드 (2,2) 등)를 정의하는 함수가 있습니다.numpy 배열을 통해 이진 구조로 반복하여 셀 합계를 얻습니다.

import numpy 
from scipy import ndimage 
a = numpy.zeros((6,6), dtype=numpy.int) 
a[1:5, 1:5] = 1;a[3,3] = 0 ; a[2,2] = 2 
s = ndimage.generate_binary_structure(2,2) # Binary structure 
#.... Calculate Sum of 
result_array = numpy.zeros_like(a) 

는 내가 원하는 주어진 구조의이 배열의 모든 셀을 반복하는 것입니다. 그런 다음 이진 구조의 모든 셀 값을 사용하는 빈 배열 (예 : 함수 합계)에 인덱싱 된 현재 셀 값에 함수를 추가하려고합니다. 예를 들어

:

array([[0, 0, 0, 0, 0, 0], 
    [0, 1, 1, 1, 1, 0], 
    [0, 1, 2, 1, 1, 0], 
    [0, 1, 1, 0, 1, 0], 
    [0, 1, 1, 1, 1, 0], 
    [0, 0, 0, 0, 0, 0]]) 

# 상기 어레이. 셀 1,2의 값은 현재 하나입니다. 구조체와 sum과 같은 예제 함수가 주어지면 결과 배열 (result_array)의 값은 7이됩니다 (현재 셀 값이 제외되면 6이됩니다).

누군가가 아이디어를 얻었습니까?

+0

어디에서 ndimage를 얻었습니까? –

+0

오, 죄송합니다. 당신은 scipy에서 가져와야합니다. 게시물을 편집했습니다 – Curlew

답변

6

을 (당신은 또한 ... 더 정교한 여기에 뭔가를 할 수), 당신은 ndimage.convolve 사용할 수 있습니다 제품의 특별한 경우를 들어

In [42]: import numpy as np 

In [43]: a = np.zeros((6,6), dtype=np.int) 
a[1:5, 1:5] = 1; 
a[3,3] = 0; 
a[2,2] = 2 

In [48]: s = ndimage.generate_binary_structure(2,2) # Binary structure 

In [49]: ndimage.convolve(a,s) 
Out[49]: 
array([[1, 2, 3, 3, 2, 1], 
     [2, 5, 7, 7, 4, 2], 
     [3, 7, 9, 9, 5, 3], 
     [3, 7, 9, 9, 5, 3], 
     [2, 4, 5, 5, 3, 2], 
     [1, 2, 3, 3, 2, 1]]) 

을, 당신은을 사용할 수 있습니다 사실 log(a*b) = log(a)+log(b)을 사용하면 문제를 다시 합계로 변환 할 수 있습니다.

b = a[1:-1, 1:-1] 
print(b) 
# [[1 1 1 1] 
# [1 2 1 1] 
# [1 1 0 1] 
# [1 1 1 1]] 

우리가 계산할 수 :

b[0,1] = -1 
print(b) 
# [[ 1 -1 1 1] 
# [ 1 2 1 1] 
# [ 1 1 0 1] 
# [ 1 1 1 1]] 

: b가 음의 값을 포함하는 경우

print(np.exp(ndimage.convolve(np.log(b), s, mode = 'constant'))) 
# [[ 2. 2. 2. 1.] 
# [ 2. 0. 0. 0.] 
# [ 2. 0. 0. 0.] 
# [ 1. 0. 0. 0.]] 

이 상황은 더 복잡하게 예를 들어, 우리는이 "제품 말다"b를 원했다 불가능하지는 않음 :

logb = np.log(b.astype('complex')) 
real, imag = logb.real, logb.imag 
print(np.real_if_close(
    np.exp(
     sum(j * ndimage.convolve(x, s, mode = 'constant') 
      for x,j in zip((real, imag),(1,1j)))))) 
# [[-2. -2. -2. 1.] 
# [-2. -0. -0. 0.] 
# [ 2. 0. 0. 0.] 
# [ 1. 0. 0. 0.]] 
+0

+1 로그를 이용한 좋은 측면 생각. – eryksun

+0

몇 가지 예를 제공해 주셔서 감사합니다. 그러나 함수 합계는 단지 예일뿐입니다. 셀 주변 값 (심지어 커스텀의 것들)에 다양한 함수를 적용하고 싶습니다. 어떻게 작동합니까? 각 셀 값에 함수 x를 적용합니까? 작업 할 셀 주변의 모든 값을 반환하는 무언가가 필요합니다 (1,2 셀에서는 [01121100,1]에서 작업해야 함) – Curlew

+1

's'을 생각해보십시오. 'a'의 각 셀에 대해 패치가 그 셀 위에 놓이고 인접한 셀이 선택되어 합산됩니다 .' convolve'는 합산 된 값으로 구성된 배열을 반환합니다 'weight'매개 변수를 사용하여 다른 가중치를 셀에 적용 할 수도 있지만 'convolve'는 항상 합계를 수행합니다.나는 임의의 함수를 제외하고는'convolve '와 같은 계산을 수행 할 수있는'scipy' 함수를 모른다. – unutbu

2

당신이 제로의 2 깊은 벽을 사용하는 경우 그것은 쉽게 :

In [11]: a0 
Out[11]: 
array([[ 0., 0., 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 1., 1., 1., 1., 0., 0.], 
     [ 0., 0., 1., 2., 1., 1., 0., 0.], 
     [ 0., 0., 1., 1., 0., 1., 0., 0.], 
     [ 0., 0., 1., 1., 1., 1., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0., 0., 0.]]) 

In [12]: b0 = zeros_like(a0) 

In [13]: for i in range(1,len(a0)-1): 
    ....:  for j in range(1,len(a0)-1): 
    ....:   b0[i,j] = sum(a0[i-1:i+2, j-1:j+2] * s) 

이 원하는대로 당신이 함께하고 합 두 개의 하위 행렬을 곱 할 수 있습니다. 금액의 특별한 경우를 들어

In [14]: b0 
Out[14]: 
array([[ 0., 0., 0., 0., 0., 0., 0., 0.], 
     [ 0., 1., 2., 3., 3., 2., 1., 0.], 
     [ 0., 2., 5., 7., 7., 4., 2., 0.], 
     [ 0., 3., 7., 9., 9., 5., 3., 0.], 
     [ 0., 3., 7., 9., 9., 5., 3., 0.], 
     [ 0., 2., 4., 5., 5., 3., 2., 0.], 
     [ 0., 1., 2., 3., 3., 2., 1., 0.], 
     [ 0., 0., 0., 0., 0., 0., 0., 0.]]) 

In [15]: b0[1:len(b0)-1, 1:len(b0)-1] 
Out[15]: 
array([[ 1., 2., 3., 3., 2., 1.], 
     [ 2., 5., 7., 7., 4., 2.], 
     [ 3., 7., 9., 9., 5., 3.], 
     [ 3., 7., 9., 9., 5., 3.], 
     [ 2., 4., 5., 5., 3., 2.], 
     [ 1., 2., 3., 3., 2., 1.]]) 
+0

함수 합계는 그 예입니다. 나는 세포 주변 값에 다양한 기능을 적용하고 싶다. 또한 대용량 배열에 직면 할 때 스크립트가 약간 느려질 수 있습니다 (두 개의 루프). 그럼에도 불구하고 +1 – Curlew

관련 문제