Fill neighboring elements in numpy array
up vote
3
down vote
favorite
Not sure whats the best way to title this question, but basically I would like to fill an existing numpy array with a value, based on the location provided and a specified distance. Assuming going diagonally is not valid.
For example, lets say we have an array with just 0s.
[[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]]
If I want (2,2) as the location with distance 1, it would fill the matrix with value 1, in the location that has distance one from the location provided, including itself. Thus the matrix would look like:
[[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]]
And if I provided a distance of 2, it would look like:
[[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]]
Basically everything within a distance of 2 from the location will be filled with the value 1. Assuming diagonal movement is not valid.
I also would like to support wrapping, where if the neighboring elements are out of bounds, it will wrap around.
For example, if the location provided is (4,4) with distance 1, the matrix should look like so:
[[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]]
I tried using np.ogrid along with a mask of where the 1's will be true but cant seem to get it working.
python numpy matrix
add a comment |
up vote
3
down vote
favorite
Not sure whats the best way to title this question, but basically I would like to fill an existing numpy array with a value, based on the location provided and a specified distance. Assuming going diagonally is not valid.
For example, lets say we have an array with just 0s.
[[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]]
If I want (2,2) as the location with distance 1, it would fill the matrix with value 1, in the location that has distance one from the location provided, including itself. Thus the matrix would look like:
[[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]]
And if I provided a distance of 2, it would look like:
[[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]]
Basically everything within a distance of 2 from the location will be filled with the value 1. Assuming diagonal movement is not valid.
I also would like to support wrapping, where if the neighboring elements are out of bounds, it will wrap around.
For example, if the location provided is (4,4) with distance 1, the matrix should look like so:
[[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]]
I tried using np.ogrid along with a mask of where the 1's will be true but cant seem to get it working.
python numpy matrix
add a comment |
up vote
3
down vote
favorite
up vote
3
down vote
favorite
Not sure whats the best way to title this question, but basically I would like to fill an existing numpy array with a value, based on the location provided and a specified distance. Assuming going diagonally is not valid.
For example, lets say we have an array with just 0s.
[[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]]
If I want (2,2) as the location with distance 1, it would fill the matrix with value 1, in the location that has distance one from the location provided, including itself. Thus the matrix would look like:
[[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]]
And if I provided a distance of 2, it would look like:
[[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]]
Basically everything within a distance of 2 from the location will be filled with the value 1. Assuming diagonal movement is not valid.
I also would like to support wrapping, where if the neighboring elements are out of bounds, it will wrap around.
For example, if the location provided is (4,4) with distance 1, the matrix should look like so:
[[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]]
I tried using np.ogrid along with a mask of where the 1's will be true but cant seem to get it working.
python numpy matrix
Not sure whats the best way to title this question, but basically I would like to fill an existing numpy array with a value, based on the location provided and a specified distance. Assuming going diagonally is not valid.
For example, lets say we have an array with just 0s.
[[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]]
If I want (2,2) as the location with distance 1, it would fill the matrix with value 1, in the location that has distance one from the location provided, including itself. Thus the matrix would look like:
[[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]]
And if I provided a distance of 2, it would look like:
[[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]]
Basically everything within a distance of 2 from the location will be filled with the value 1. Assuming diagonal movement is not valid.
I also would like to support wrapping, where if the neighboring elements are out of bounds, it will wrap around.
For example, if the location provided is (4,4) with distance 1, the matrix should look like so:
[[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]]
I tried using np.ogrid along with a mask of where the 1's will be true but cant seem to get it working.
python numpy matrix
python numpy matrix
asked Nov 9 at 16:22
user1179317
590718
590718
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
up vote
3
down vote
accepted
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]])
add a comment |
up vote
1
down vote
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.]])
add a comment |
up vote
0
down vote
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
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
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]])
add a comment |
up vote
3
down vote
accepted
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]])
add a comment |
up vote
3
down vote
accepted
up vote
3
down vote
accepted
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]])
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]])
edited Nov 9 at 17:14
answered Nov 9 at 16:49
sacul
27.5k41639
27.5k41639
add a comment |
add a comment |
up vote
1
down vote
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.]])
add a comment |
up vote
1
down vote
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.]])
add a comment |
up vote
1
down vote
up vote
1
down vote
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.]])
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.]])
answered Nov 9 at 16:50
Alex
10.2k32355
10.2k32355
add a comment |
add a comment |
up vote
0
down vote
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
add a comment |
up vote
0
down vote
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
add a comment |
up vote
0
down vote
up vote
0
down vote
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
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
edited Nov 9 at 16:57
answered Nov 9 at 16:52
Vikhyat Agarwal
410214
410214
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53229562%2ffill-neighboring-elements-in-numpy-array%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown