How to shift elements in a numpy array ?


Introduction

Numpy arrays are multi-dimensional data structures that can hold elements of the same data type.

One of the common tasks you may encounter when working with numpy arrays is shifting elements within an array. In this article, we will discuss how to shift elements in a numpy array using different methods.

Rearranging Elements using the numpy roll() Function for a 1D Array

To begin, we can create a basic 1D array using the np.array() function:

import numpy as np

data = np.arange(1,10)

print( data )

Output:

array([1, 2, 3, 4, 5, 6, 7, 8, 9])

Moving elements forward by n positions

To shift an element by n positions, we can utilize the numpy roll function. For instance, if we want to shift our element by 2:

n = 2

new_data = np.roll(data,shift=n)

print(new_data)

The code mentioned above will provide:

array([8, 9, 1, 2, 3, 4, 5, 6, 7])

if you goal is to shift your elements by n but not replacing the element below. A straightforward solution is to do define a default value and using numpy slice approach:

default_value =  -999

new_data[:n] = default_value

print(new_data)

The code mentioned above will provide:

array([-999, -999,    1,    2,    3,    4,    5,    6,    7])

Moving elements backward by n positions

To shift an element by n positions, we can utilize the numpy roll function. For instance, if we want to shift our element by -3:

n = -3

new_data = np.roll(data,n)

print(new_data)

The code mentioned above will provide:

array([4 5 6 7 8 9 1 2 3])

if you goal is to shift your elements by n but not replacing the element below. A straightforward solution is to do define a default value and using numpy slice approach:

default_value =  -999

new_data[n:] = default_value

print(new_data)

The code mentioned above will provide:

array([   4,    5,    6,    7,    8,    9, -999, -999, -999])

Please note that the slicing in this case differs slightly from the previous scenario when n is positive.

Rearranging Elements for a 2D Array

Using the numpy roll() Function

To demonstrate how to shift elements in a 2D array, let's start by creating one:

import numpy as np

data = np.arange(1,31).reshape(5,6)

print(data)

Output

array([[ 1,  2,  3,  4,  5,  6],
       [ 7,  8,  9, 10, 11, 12],
       [13, 14, 15, 16, 17, 18],
       [19, 20, 21, 22, 23, 24],
       [25, 26, 27, 28, 29, 30]])

Then, by applying the roll() function without specifying the axis:

n = 2

new_data = np.roll(data,n)

print(new_data)

you will observe the following outcome:

[[29 30  1  2  3  4]
 [ 5  6  7  8  9 10]
 [11 12 13 14 15 16]
 [17 18 19 20 21 22]
 [23 24 25 26 27 28]]

To achieve the same result, you can flatten the 2D array and apply the roll function as before. Finally, reshape the array back to its original shape.

new_data = data.flatten()

new_data = np.roll(data,n)

new_data = new_data.reshape(data.shape)

Shifting elements in a 2D array along the rows.

To utilize the numpy.roll() function for moving elements across the rows of a 2D array, you indicate the shift along the specified axis. For instance, if your goal is to roll elements n positions to the right across rows in a 2D array, you'd use np.roll(my_array, shift=n, axis=0).

Each row's elements move independently of the others, wrapping around to the start of the row as necessary.

n = 2

new_data = np.roll(data,n, axis=0)

print(new_data)

Output

[[19 20 21 22 23 24]
 [25 26 27 28 29 30]
 [ 1  2  3  4  5  6]
 [ 7  8  9 10 11 12]
 [13 14 15 16 17 18]]

To move elements left, use a negative shift value instead.

Shifting elements in a 2D array along the columns.

n = 2

new_data = np.roll(data,n, axis=1)

print(new_data)

Output

[[ 5  6  1  2  3  4]
 [11 12  7  8  9 10]
 [17 18 13 14 15 16]
 [23 24 19 20 21 22]
 [29 30 25 26 27 28]]

Utilizing the shift function from the scipy ndimage library

Another option is to utilize the shift function from the scipy ndimage library. This powerful tool enables swift and efficient manipulation of array elements, ensuring optimal performance.

For example, a solution to shift both the columns and rows by 2 is to do the following:

from scipy.ndimage import shift

new_data = shift(data, shift=2, cval=0)

print(new_data)

Output

[[ 0  0  0  0  0  0]
 [ 0  0  0  0  0  0]
 [ 0  0  1  2  3  4]
 [ 0  0  7  8  9 10]
 [ 0  0 13 14 15 16]]

It is also possible to specify varying shifts for different axes by using a sequence such as a tuple or list. For instance, you can shift by one in the row but by three in the columns:

new_data = shift(data, shift=[1,3], cval=0)

print(new_data)

Output

[[ 0  0  0  0  0  0]
 [ 0  0  0  1  2  3]
 [ 0  0  0  7  8  9]
 [ 0  0  0 13 14 15]
 [ 0  0  0 19 20 21]]

References

Links Site
numpy.roll numpy.org
scipy.ndimage.shift docs.scipy.org