Best way to go towards an index in numpy, with wrap
up vote
1
down vote
favorite
Lets say I have a 2D array below:
[[ 0 0 0 0 0 0 ]
[ 0 0 0 0 0 0 ]
[ 0 0 0 0 0 0 ]
[ 0 0 0 0 0 2 ]
[ 0 1 0 0 0 0 ]
[ 0 0 0 0 0 0 ]]
I would like to get the direction from where '1' (index 4,1) is to '2' (index 3,5). Assuming directions are only up, down, left, right. Thus no diagonal movement.
One way to get the directions:
"right" if destination.x > start.x else "left" if target.x < start.x else None
"down" if destination.y > start.y else "up" if destination.y < start.y else None
So for this example, we can go to '2' or the destination by either going "up" or "right". That of course is just one step, once you moved, can perform the same logic to move closer to the destination.
The problem with this logic is that it doesnt take the wrapping into account. With this logic it will take 5 steps to get to the destination. There is a shorter way by actually going left or up that can get to the destination in just 3 steps, because of the wrap.
Was thinking of generating another array where the start will be the middle of the array and perform the same logic. The problem is if the array is even (like this is 6x6, need to pad to get a middle. For example:
[[ 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0]
[ 0 2 0 0 0 0 0]
[ 0 0 0 1 0 0 0]
[ 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0]]
Here the array is now 7x7. I believe there is a simplier way to get the answer without this extra step, but cant think of it.
python arrays numpy matrix
add a comment |
up vote
1
down vote
favorite
Lets say I have a 2D array below:
[[ 0 0 0 0 0 0 ]
[ 0 0 0 0 0 0 ]
[ 0 0 0 0 0 0 ]
[ 0 0 0 0 0 2 ]
[ 0 1 0 0 0 0 ]
[ 0 0 0 0 0 0 ]]
I would like to get the direction from where '1' (index 4,1) is to '2' (index 3,5). Assuming directions are only up, down, left, right. Thus no diagonal movement.
One way to get the directions:
"right" if destination.x > start.x else "left" if target.x < start.x else None
"down" if destination.y > start.y else "up" if destination.y < start.y else None
So for this example, we can go to '2' or the destination by either going "up" or "right". That of course is just one step, once you moved, can perform the same logic to move closer to the destination.
The problem with this logic is that it doesnt take the wrapping into account. With this logic it will take 5 steps to get to the destination. There is a shorter way by actually going left or up that can get to the destination in just 3 steps, because of the wrap.
Was thinking of generating another array where the start will be the middle of the array and perform the same logic. The problem is if the array is even (like this is 6x6, need to pad to get a middle. For example:
[[ 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0]
[ 0 2 0 0 0 0 0]
[ 0 0 0 1 0 0 0]
[ 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0]]
Here the array is now 7x7. I believe there is a simplier way to get the answer without this extra step, but cant think of it.
python arrays numpy matrix
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
Lets say I have a 2D array below:
[[ 0 0 0 0 0 0 ]
[ 0 0 0 0 0 0 ]
[ 0 0 0 0 0 0 ]
[ 0 0 0 0 0 2 ]
[ 0 1 0 0 0 0 ]
[ 0 0 0 0 0 0 ]]
I would like to get the direction from where '1' (index 4,1) is to '2' (index 3,5). Assuming directions are only up, down, left, right. Thus no diagonal movement.
One way to get the directions:
"right" if destination.x > start.x else "left" if target.x < start.x else None
"down" if destination.y > start.y else "up" if destination.y < start.y else None
So for this example, we can go to '2' or the destination by either going "up" or "right". That of course is just one step, once you moved, can perform the same logic to move closer to the destination.
The problem with this logic is that it doesnt take the wrapping into account. With this logic it will take 5 steps to get to the destination. There is a shorter way by actually going left or up that can get to the destination in just 3 steps, because of the wrap.
Was thinking of generating another array where the start will be the middle of the array and perform the same logic. The problem is if the array is even (like this is 6x6, need to pad to get a middle. For example:
[[ 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0]
[ 0 2 0 0 0 0 0]
[ 0 0 0 1 0 0 0]
[ 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0]]
Here the array is now 7x7. I believe there is a simplier way to get the answer without this extra step, but cant think of it.
python arrays numpy matrix
Lets say I have a 2D array below:
[[ 0 0 0 0 0 0 ]
[ 0 0 0 0 0 0 ]
[ 0 0 0 0 0 0 ]
[ 0 0 0 0 0 2 ]
[ 0 1 0 0 0 0 ]
[ 0 0 0 0 0 0 ]]
I would like to get the direction from where '1' (index 4,1) is to '2' (index 3,5). Assuming directions are only up, down, left, right. Thus no diagonal movement.
One way to get the directions:
"right" if destination.x > start.x else "left" if target.x < start.x else None
"down" if destination.y > start.y else "up" if destination.y < start.y else None
So for this example, we can go to '2' or the destination by either going "up" or "right". That of course is just one step, once you moved, can perform the same logic to move closer to the destination.
The problem with this logic is that it doesnt take the wrapping into account. With this logic it will take 5 steps to get to the destination. There is a shorter way by actually going left or up that can get to the destination in just 3 steps, because of the wrap.
Was thinking of generating another array where the start will be the middle of the array and perform the same logic. The problem is if the array is even (like this is 6x6, need to pad to get a middle. For example:
[[ 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0]
[ 0 2 0 0 0 0 0]
[ 0 0 0 1 0 0 0]
[ 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0]]
Here the array is now 7x7. I believe there is a simplier way to get the answer without this extra step, but cant think of it.
python arrays numpy matrix
python arrays numpy matrix
asked Nov 11 at 18:31
user1179317
602818
602818
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
up vote
0
down vote
Can you consider using this method?
import numpy as np
# build the array
a = np.zeros( (6,6), dtype=int )
a[4][1] = 1
a[3][5] = 2
# extract required informations
i,j = np.where(a == 1)
h,k =np.where(a == 2)
print (i-h) => [1]
print (j-k) => [-4]
Not sure if i get your answer. Are you saying to use the same logic I had but have 1, -4 as the new destination? If so yes for this scenario this works, where it'll tell me to go "left" or "up" instead. But in a scenario where "1" is located in 4,1 and "2" at 3, 2 it should go "up" or "right", where using your logic will give "left" or "up" where left is actually going away
– user1179317
Nov 11 at 20:05
add a comment |
up vote
0
down vote
Well, there is a quite simple formula for computing the distance in case of periodic boundary conditions. Below I consider only periodic b.c. on x-axis:
import numpy as np
# periodic boundary condition for the x-axis only
def steps(start, dest, L_x):
x_start = start[1]
y_start = start[0]
x_dest = dest[1]
y_dest = dest[0]
dx = x_dest - x_start
if np.abs(dx) <= L_x/2:
steps_x = x_dest - x_start
else:
if dx > 0:
steps_x = (x_dest - L_x) - x_start
else:
steps_x = (x_dest + L_x) - x_start
steps_y = y_dest - y_start
return steps_x, steps_y
Example:
grid = np.array([[0, 0, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 2 ],
[0, 1, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 0 ]])
L_x = grid.shape[1]
start = (4, 1) # (y, x) or (i, j)
dest = (3, 5)
steps_x, steps_y = steps(start, dest, grid)
dir_x = 'left' if steps_x < 0 else 'right'
dir_y = 'up' if steps_y < 0 else 'down'
print(abs(steps_x), dir_x, ',', abs(steps_y), dir_y)
Out: 2 left , 1 up
add a comment |
up vote
0
down vote
I try an other way:
On an horizontal axis of length size
, to go from a
to b
, let delta = ((b-a)%size*2-1)//size
.
- if
delta=-1
,a=b
: you don't move. - if
delta=0
: you have to go right. - if
delta=1
: you have to go left.
So this code seems works
size=10
vertical=['down','up',None]
horizontal=['right','left',None]
def side(a,b):
return ((b-a)%size*2-1)//size
def step(M1,M2):
x1,y1=M1
x2,y2=M2
return (vertical[side(x1,x2)],horizontal[side(y1,y2)])
For example :
In [6]: step((2,1),(2,8))
Out[6]: (None, 'left')
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
Can you consider using this method?
import numpy as np
# build the array
a = np.zeros( (6,6), dtype=int )
a[4][1] = 1
a[3][5] = 2
# extract required informations
i,j = np.where(a == 1)
h,k =np.where(a == 2)
print (i-h) => [1]
print (j-k) => [-4]
Not sure if i get your answer. Are you saying to use the same logic I had but have 1, -4 as the new destination? If so yes for this scenario this works, where it'll tell me to go "left" or "up" instead. But in a scenario where "1" is located in 4,1 and "2" at 3, 2 it should go "up" or "right", where using your logic will give "left" or "up" where left is actually going away
– user1179317
Nov 11 at 20:05
add a comment |
up vote
0
down vote
Can you consider using this method?
import numpy as np
# build the array
a = np.zeros( (6,6), dtype=int )
a[4][1] = 1
a[3][5] = 2
# extract required informations
i,j = np.where(a == 1)
h,k =np.where(a == 2)
print (i-h) => [1]
print (j-k) => [-4]
Not sure if i get your answer. Are you saying to use the same logic I had but have 1, -4 as the new destination? If so yes for this scenario this works, where it'll tell me to go "left" or "up" instead. But in a scenario where "1" is located in 4,1 and "2" at 3, 2 it should go "up" or "right", where using your logic will give "left" or "up" where left is actually going away
– user1179317
Nov 11 at 20:05
add a comment |
up vote
0
down vote
up vote
0
down vote
Can you consider using this method?
import numpy as np
# build the array
a = np.zeros( (6,6), dtype=int )
a[4][1] = 1
a[3][5] = 2
# extract required informations
i,j = np.where(a == 1)
h,k =np.where(a == 2)
print (i-h) => [1]
print (j-k) => [-4]
Can you consider using this method?
import numpy as np
# build the array
a = np.zeros( (6,6), dtype=int )
a[4][1] = 1
a[3][5] = 2
# extract required informations
i,j = np.where(a == 1)
h,k =np.where(a == 2)
print (i-h) => [1]
print (j-k) => [-4]
answered Nov 11 at 19:21
iGian
2,8542622
2,8542622
Not sure if i get your answer. Are you saying to use the same logic I had but have 1, -4 as the new destination? If so yes for this scenario this works, where it'll tell me to go "left" or "up" instead. But in a scenario where "1" is located in 4,1 and "2" at 3, 2 it should go "up" or "right", where using your logic will give "left" or "up" where left is actually going away
– user1179317
Nov 11 at 20:05
add a comment |
Not sure if i get your answer. Are you saying to use the same logic I had but have 1, -4 as the new destination? If so yes for this scenario this works, where it'll tell me to go "left" or "up" instead. But in a scenario where "1" is located in 4,1 and "2" at 3, 2 it should go "up" or "right", where using your logic will give "left" or "up" where left is actually going away
– user1179317
Nov 11 at 20:05
Not sure if i get your answer. Are you saying to use the same logic I had but have 1, -4 as the new destination? If so yes for this scenario this works, where it'll tell me to go "left" or "up" instead. But in a scenario where "1" is located in 4,1 and "2" at 3, 2 it should go "up" or "right", where using your logic will give "left" or "up" where left is actually going away
– user1179317
Nov 11 at 20:05
Not sure if i get your answer. Are you saying to use the same logic I had but have 1, -4 as the new destination? If so yes for this scenario this works, where it'll tell me to go "left" or "up" instead. But in a scenario where "1" is located in 4,1 and "2" at 3, 2 it should go "up" or "right", where using your logic will give "left" or "up" where left is actually going away
– user1179317
Nov 11 at 20:05
add a comment |
up vote
0
down vote
Well, there is a quite simple formula for computing the distance in case of periodic boundary conditions. Below I consider only periodic b.c. on x-axis:
import numpy as np
# periodic boundary condition for the x-axis only
def steps(start, dest, L_x):
x_start = start[1]
y_start = start[0]
x_dest = dest[1]
y_dest = dest[0]
dx = x_dest - x_start
if np.abs(dx) <= L_x/2:
steps_x = x_dest - x_start
else:
if dx > 0:
steps_x = (x_dest - L_x) - x_start
else:
steps_x = (x_dest + L_x) - x_start
steps_y = y_dest - y_start
return steps_x, steps_y
Example:
grid = np.array([[0, 0, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 2 ],
[0, 1, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 0 ]])
L_x = grid.shape[1]
start = (4, 1) # (y, x) or (i, j)
dest = (3, 5)
steps_x, steps_y = steps(start, dest, grid)
dir_x = 'left' if steps_x < 0 else 'right'
dir_y = 'up' if steps_y < 0 else 'down'
print(abs(steps_x), dir_x, ',', abs(steps_y), dir_y)
Out: 2 left , 1 up
add a comment |
up vote
0
down vote
Well, there is a quite simple formula for computing the distance in case of periodic boundary conditions. Below I consider only periodic b.c. on x-axis:
import numpy as np
# periodic boundary condition for the x-axis only
def steps(start, dest, L_x):
x_start = start[1]
y_start = start[0]
x_dest = dest[1]
y_dest = dest[0]
dx = x_dest - x_start
if np.abs(dx) <= L_x/2:
steps_x = x_dest - x_start
else:
if dx > 0:
steps_x = (x_dest - L_x) - x_start
else:
steps_x = (x_dest + L_x) - x_start
steps_y = y_dest - y_start
return steps_x, steps_y
Example:
grid = np.array([[0, 0, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 2 ],
[0, 1, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 0 ]])
L_x = grid.shape[1]
start = (4, 1) # (y, x) or (i, j)
dest = (3, 5)
steps_x, steps_y = steps(start, dest, grid)
dir_x = 'left' if steps_x < 0 else 'right'
dir_y = 'up' if steps_y < 0 else 'down'
print(abs(steps_x), dir_x, ',', abs(steps_y), dir_y)
Out: 2 left , 1 up
add a comment |
up vote
0
down vote
up vote
0
down vote
Well, there is a quite simple formula for computing the distance in case of periodic boundary conditions. Below I consider only periodic b.c. on x-axis:
import numpy as np
# periodic boundary condition for the x-axis only
def steps(start, dest, L_x):
x_start = start[1]
y_start = start[0]
x_dest = dest[1]
y_dest = dest[0]
dx = x_dest - x_start
if np.abs(dx) <= L_x/2:
steps_x = x_dest - x_start
else:
if dx > 0:
steps_x = (x_dest - L_x) - x_start
else:
steps_x = (x_dest + L_x) - x_start
steps_y = y_dest - y_start
return steps_x, steps_y
Example:
grid = np.array([[0, 0, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 2 ],
[0, 1, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 0 ]])
L_x = grid.shape[1]
start = (4, 1) # (y, x) or (i, j)
dest = (3, 5)
steps_x, steps_y = steps(start, dest, grid)
dir_x = 'left' if steps_x < 0 else 'right'
dir_y = 'up' if steps_y < 0 else 'down'
print(abs(steps_x), dir_x, ',', abs(steps_y), dir_y)
Out: 2 left , 1 up
Well, there is a quite simple formula for computing the distance in case of periodic boundary conditions. Below I consider only periodic b.c. on x-axis:
import numpy as np
# periodic boundary condition for the x-axis only
def steps(start, dest, L_x):
x_start = start[1]
y_start = start[0]
x_dest = dest[1]
y_dest = dest[0]
dx = x_dest - x_start
if np.abs(dx) <= L_x/2:
steps_x = x_dest - x_start
else:
if dx > 0:
steps_x = (x_dest - L_x) - x_start
else:
steps_x = (x_dest + L_x) - x_start
steps_y = y_dest - y_start
return steps_x, steps_y
Example:
grid = np.array([[0, 0, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 2 ],
[0, 1, 0, 0, 0, 0 ],
[0, 0, 0, 0, 0, 0 ]])
L_x = grid.shape[1]
start = (4, 1) # (y, x) or (i, j)
dest = (3, 5)
steps_x, steps_y = steps(start, dest, grid)
dir_x = 'left' if steps_x < 0 else 'right'
dir_y = 'up' if steps_y < 0 else 'down'
print(abs(steps_x), dir_x, ',', abs(steps_y), dir_y)
Out: 2 left , 1 up
edited Nov 11 at 21:52
answered Nov 11 at 20:53
AndyK
828718
828718
add a comment |
add a comment |
up vote
0
down vote
I try an other way:
On an horizontal axis of length size
, to go from a
to b
, let delta = ((b-a)%size*2-1)//size
.
- if
delta=-1
,a=b
: you don't move. - if
delta=0
: you have to go right. - if
delta=1
: you have to go left.
So this code seems works
size=10
vertical=['down','up',None]
horizontal=['right','left',None]
def side(a,b):
return ((b-a)%size*2-1)//size
def step(M1,M2):
x1,y1=M1
x2,y2=M2
return (vertical[side(x1,x2)],horizontal[side(y1,y2)])
For example :
In [6]: step((2,1),(2,8))
Out[6]: (None, 'left')
add a comment |
up vote
0
down vote
I try an other way:
On an horizontal axis of length size
, to go from a
to b
, let delta = ((b-a)%size*2-1)//size
.
- if
delta=-1
,a=b
: you don't move. - if
delta=0
: you have to go right. - if
delta=1
: you have to go left.
So this code seems works
size=10
vertical=['down','up',None]
horizontal=['right','left',None]
def side(a,b):
return ((b-a)%size*2-1)//size
def step(M1,M2):
x1,y1=M1
x2,y2=M2
return (vertical[side(x1,x2)],horizontal[side(y1,y2)])
For example :
In [6]: step((2,1),(2,8))
Out[6]: (None, 'left')
add a comment |
up vote
0
down vote
up vote
0
down vote
I try an other way:
On an horizontal axis of length size
, to go from a
to b
, let delta = ((b-a)%size*2-1)//size
.
- if
delta=-1
,a=b
: you don't move. - if
delta=0
: you have to go right. - if
delta=1
: you have to go left.
So this code seems works
size=10
vertical=['down','up',None]
horizontal=['right','left',None]
def side(a,b):
return ((b-a)%size*2-1)//size
def step(M1,M2):
x1,y1=M1
x2,y2=M2
return (vertical[side(x1,x2)],horizontal[side(y1,y2)])
For example :
In [6]: step((2,1),(2,8))
Out[6]: (None, 'left')
I try an other way:
On an horizontal axis of length size
, to go from a
to b
, let delta = ((b-a)%size*2-1)//size
.
- if
delta=-1
,a=b
: you don't move. - if
delta=0
: you have to go right. - if
delta=1
: you have to go left.
So this code seems works
size=10
vertical=['down','up',None]
horizontal=['right','left',None]
def side(a,b):
return ((b-a)%size*2-1)//size
def step(M1,M2):
x1,y1=M1
x2,y2=M2
return (vertical[side(x1,x2)],horizontal[side(y1,y2)])
For example :
In [6]: step((2,1),(2,8))
Out[6]: (None, 'left')
edited Nov 12 at 14:55
answered Nov 12 at 14:19
B. M.
12.6k11934
12.6k11934
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
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%2f53251860%2fbest-way-to-go-towards-an-index-in-numpy-with-wrap%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