Fill neighboring elements in numpy array
Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn
--
Music by Eric Matyas
https://www.soundimage.org
Track title: The Builders
--
Chapters
00:00 Question
01:44 Accepted answer (Score 5)
03:11 Answer 2 (Score 1)
03:37 Answer 3 (Score 0)
04:21 Thank you
--
Full question
https://stackoverflow.com/questions/5322...
Accepted answer links:
[binary dilation]: https://docs.scipy.org/doc/scipy-0.14.0/...
[grey dilation]: https://docs.scipy.org/doc/scipy-0.14.0/...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #numpy #matrix
#avk47
--
Music by Eric Matyas
https://www.soundimage.org
Track title: The Builders
--
Chapters
00:00 Question
01:44 Accepted answer (Score 5)
03:11 Answer 2 (Score 1)
03:37 Answer 3 (Score 0)
04:21 Thank you
--
Full question
https://stackoverflow.com/questions/5322...
Accepted answer links:
[binary dilation]: https://docs.scipy.org/doc/scipy-0.14.0/...
[grey dilation]: https://docs.scipy.org/doc/scipy-0.14.0/...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #numpy #matrix
#avk47
ACCEPTED ANSWER
Score 5
What you are trying to do is essentially binary dilation, but the wrapping poses a problem. Luckily, scipy's grey dilation function has the wrap mode which we can leverage:
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')
And as a function that creates your array for you:
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')
Examples: To reproduce your desired inputs and outputs:
>>> 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]])
ANSWER 2
Score 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))
returns
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.]])
ANSWER 3
Score 0
This may not be the most efficient solution but you could try iterating through all the elements in the array, check if their distance to the location provided is what you want it to be and if it is, replace that element's value with the value specified. Basic code structure:
# 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
The distanceToPoint function would be something like this:
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