Evan Pu
Evan Pu

Reputation: 2187

How to translate / shift a numpy array?

I am not sure what key-word to search for so if it has been already asked please link the response and close this thread.

I am trying to shift the non-zero entries of a numpy array by a fixed direction, for instance, imagine I have a 2d array:

0 1 2 0
0 3 0 0
0 0 0 0
0 0 0 0

Shifting it by (1,1) would produce the following array:

0 0 0 0
0 0 1 2
0 0 3 0
0 0 0 0

Let's say if the non-zero entries goes out of bound they're simply dropped. How might I do this?

edit: aparently some duplicate from this? Shift elements in a numpy array I don't really see why are they the same question at all because that one talks about looping the things out of bound around, so it's more of a "rolling" action rather than shifting. Also I liked the solution here, it is very simple and readable.

edit again: fixed some formats

Upvotes: 3

Views: 15974

Answers (2)

Adrien Pavao
Adrien Pavao

Reputation: 461

Using roll method from numpy.

>>> import numpy as np
>>> m
array([[0, 1, 2, 0],
       [0, 3, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0]])
>>> m = np.roll(m, 1, axis=0) # shift 1 place in horizontal axis
>>> m = np.roll(m, 1, axis=1) # shift 1 place in vertical axis
>>> m
array([[0, 0, 0, 0],
       [0, 0, 1, 2],
       [0, 0, 3, 0],
       [0, 0, 0, 0]])

https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.roll.html

Upvotes: 6

B. M.
B. M.

Reputation: 18628

To simply manage the edges, you can enlarge your array in a bigger one :

square=\
array([[0, 2, 2, 0],
       [0, 2, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0]], dtype=int64)

n,m=square.shape
bigsquare=np.zeros((3*n,3*m),square.dtype) 
bigsquare[n:2*n,m:2*m]=square

Then shift is just a view :

def shift(dx,dy):
    x=n-dx
    y=m-dy
    return bigsquare[x:x+n,y:y+m]

print(shift(1,1))

#[[0 0 0 0]
# [0 0 2 2]
# [0 0 2 0]
# [0 0 0 0]]

Upvotes: 2

Related Questions