Home > Net >  Shift a numpy array by an increasing value with each row
Shift a numpy array by an increasing value with each row

Time:03-02

I have a numpy array I'll use np.ones((2,3)) as a MWE:

arr = [[1,1,1], 
       [1,1,1], 
       [1,1,1]] 

I wish to shift the rows by a set integer. This will increase with the row. Shift the 1st row by 0 shift the 5th row by 4

I imagine the row length will have to be equal for all rows giving something list this: to give this:

arr = [[1,1,1,0,0], 
       [0,1,1,1,0], 
       [0,0,1,1,1]] 

This is a MWE and the actual arrays are taken from txt files and are up to (1000x96). The important values are not just 1 but any float from 0->inf.

Is there a way of doing this?

(Extra information: these data are for 2D heatmap plotting)

CodePudding user response:

I have the following solution:

import numpy as np
arr = [[1,1,1], 
       [1,1,1], 
       [1,1,1], 
       [1,1,1]] 
arr = np.array(arr)
shift = 1
extend = shift*(np.shape(arr)[0]-1)
arr2 = np.zeros((np.shape(arr)[0],extend np.shape(arr)[1]))
for i,row in enumerate(arr):
    arr2[i,(i*shift):(i*shift) 3] = row
print(arr2)
[[1. 1. 1. 0. 0. 0.]
 [0. 1. 1. 1. 0. 0.]
 [0. 0. 1. 1. 1. 0.]
 [0. 0. 0. 1. 1. 1.]]

CodePudding user response:

Assuming an array with arbitrary values, you could use:

# add enough "0" columns for the shift
arr2 = np.c_[arr, np.zeros((arr.shape[0], arr.shape[0]-1), dtype=arr.dtype)]
# get the indices as ogrid
r, c = np.ogrid[:arr2.shape[0], :arr2.shape[1]]
# roll the values
arr2 = arr2[r, c-r]

used input:

arr = np.arange(1,10).reshape(3,3)
# array([[1, 2, 3],
#        [4, 5, 6],
#        [7, 8, 9]])

output:

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