Заполните соседние элементы в массиве NumPy - PullRequest
0 голосов
/ 09 ноября 2018

Не знаю, как лучше всего озаглавить этот вопрос, но в основном я хотел бы заполнить существующий массив с пустыми значениями, основываясь на предоставленном местоположении и указанном расстоянии. Предполагается, что движение по диагонали недопустимо.

Например, допустим, у нас есть массив только с 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 в местоположении, которое имеет расстояние один от предоставленного местоположения, включая себя. Таким образом, матрица будет выглядеть так:

[[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 будут истинными, но, похоже, он не работает.

Ответы [ 3 ]

0 голосов
/ 09 ноября 2018
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.]])
0 голосов
/ 09 ноября 2018

Возможно, это не самое эффективное решение, но вы можете попробовать перебрать все элементы в массиве, проверить, соответствует ли их расстояние до указанного местоположения, и если это так, заменить значение этого элемента на указанное значение. Базовая структура кода:

# 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
0 голосов
/ 09 ноября 2018

То, что вы пытаетесь сделать, это, по сути, двоичное расширение , но перенос создает проблему. К счастью, функция 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]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...