簡體   English   中英

填充numpy數組中的相鄰元素

[英]Fill neighboring elements in numpy array

不知道什么是標題這個問題的最好方法,但基本上我想根據提供的位置和指定的距離用現有的numpy數組填充一個值。 假設對角線無效。

例如,假設我們有一個只有0的數組。

[[0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 0 0 0]]

如果我想要(2,2)作為距離1的位置,它將填充矩陣的值為1,位於距離提供的位置1的位置,包括其自身。 因此矩陣看起來像:

[[0 0 0 0 0]
 [0 0 1 0 0]
 [0 1 1 1 0]
 [0 0 1 0 0]
 [0 0 0 0 0]]

如果我提供的距離為2,它看起來像:

[[0 0 1 0 0]
 [0 1 1 1 0]
 [1 1 1 1 1]
 [0 1 1 1 0]
 [0 0 1 0 0]]

基本上距離該位置2的距離內的所有內容都將填充值1.假設對角線移動無效。

我也想支持包裝,如果相鄰的元素超出范圍,它將環繞。

例如,如果提供的位置是(4,4)距離為1,則矩陣應如下所示:

[[0 0 0 0 1]
 [0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 0 0 1]
 [1 0 0 1 1]]

我嘗試使用np.ogrid以及1將是真實的掩碼,但似乎無法使其正常工作。

你要做的實際上是二元擴張 ,但包裹帶來了問題。 幸運的是, scipy灰色擴張功能具有我們可以利用的wrap模式:

from scipy.ndimage.morphology import grey_dilation, generate_binary_structure, iterate_structure

st = generate_binary_structure(2,1)

# st essentially defines "neighbours", 
# and you can expand n times this using iterate_structure(st, n):

# >>> st
# array([[False,  True, False],
#        [ True,  True,  True],
#        [False,  True, False]])

# >>> iterate_structure(st,2)
# array([[False, False,  True, False, False],
#        [False,  True,  True,  True, False],
#        [ True,  True,  True,  True,  True],
#        [False,  True,  True,  True, False],
#        [False, False,  True, False, False]])


a = np.zeros((5,5))
a[4,4] = 1
dist = 1

dilated = grey_dilation(a, footprint = iterate_structure(st,dist), mode='wrap')

並且作為為您創建陣列的函數:

from scipy.ndimage.morphology import grey_dilation, generate_binary_structure, iterate_structure

def create(size, dist, loc):
    a = np.zeros((size,size), dtype=int)
    a[loc] = 1
    st = generate_binary_structure(2,1)
    return grey_dilation(a, footprint = iterate_structure(st,dist), mode='wrap')

示例 :重現所需的輸入和輸出:

>>> create(5, 1, (2,2))
array([[0, 0, 0, 0, 0],
       [0, 0, 1, 0, 0],
       [0, 1, 1, 1, 0],
       [0, 0, 1, 0, 0],
       [0, 0, 0, 0, 0]])

>>> create(5, 2, (2,2))
array([[0, 0, 1, 0, 0],
       [0, 1, 1, 1, 0],
       [1, 1, 1, 1, 1],
       [0, 1, 1, 1, 0],
       [0, 0, 1, 0, 0]])

>>> create(5, 1, (4,4))
array([[0, 0, 0, 0, 1],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 1],
       [1, 0, 0, 1, 1]])
def create(size, dist, loc):
    a = np.zeros((size, size))
    for i in range(-dist, dist + 1):
        for j in range(-dist + abs(i), dist - abs(i) + 1):
            i_ = (i + loc[0]) % size
            j_ = (j + loc[1]) % size
            a[i_, j_] = 1
    return a

create(5, 1, (4, 4))

回報

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

這可能不是最有效的解決方案,但您可以嘗試遍歷數組中的所有元素,檢查它們到所提供位置的距離是否是您想要的,如果是,請將該元素的值替換為指定的值。 基本代碼結構:

# declar my_arr
value = 1
distance = 2
centre_point = (4,4)
for row_index in range(len(my_arr)):
    for col_index in range(len(my_arr[row_index])):
        if distanceToPoint(row_index,col_index,centre_point) <= distance:
            my_arr[row_index][col_index] = value

distanceToPoint函數將是這樣的:

def distanceToPoint(x,y,point):
   px,py = point
   dx,dy = px-x,py-y
   if x==px:
       return py-y
   if y==py:
       return px-x
   if abs(dx)==abs(dy):
       return dx
   else:
       return 1000000 #an arbitrarily large amount which should be bigger than distance

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM