A = np.array([[4, 3, 2],
[1, 2, 3],
[0, -1, 5]])
shift = np.array([1,2,1])
out = np.array([[3, 2, np.nan],
[3, np.nan, np.nan],
[-1, 5, np.nan]])
I want to left shift the 2D numpy array towards the left for each row independently as given by the shift vector and impute the right with Nan.
Please help me out with this
Thanks
CodePudding user response:
import numpy as np
A = np.array([[4, 3, 2],
[1, 2, 3],
[0, -1, 5]])
shift = np.array([1,2,1])
x,y = A.shape
res = np.full(x*y,np.nan).reshape(x,y)
for i in range(x):
for j in range(y):
res[i][:(y-shift[i])]=A[i][shift[i]:]
print(res)
CodePudding user response:
Using Roll rows of matrix Ref
from skimage.util.shape import view_as_windows as viewW
import numpy as np
A = np.array([[4, 3, 2],
[1, 2, 3],
[0, -1, 5]])
shift = np.array([1,1,1])
p = np.full((A.shape[0],A.shape[1]-1),np.nan)
a_ext = np.concatenate((A,p,p),axis=1)
n = A.shape[1]
shifted =viewW(a_ext,(1,n))[np.arange(len(shift)), -shift (n-1),0]
print(shifted)
output #
[[ 3. 2. nan]
[ 2. 3. nan]
[-1. 5. nan]]
CodePudding user response:
you should just use a for loop and np.roll per row.
import numpy as np
A = np.array([[4, 3, 2],
[1, 2, 3],
[0, -1, 5]]).astype(float)
shift = np.array([1,2,1])
out = np.copy(A)
for i,shift_value in enumerate(shift):
out[i,:shift_value] = np.nan
out[i,:] = np.roll(out[i,:],-shift_value)
print(out)
[[ 3. 2. nan]
[ 3. nan nan]
[-1. 5. nan]]
while someone might think that reducing the calls to np.roll
will help, it won't because this is exactly the way np.roll
is implemented internally, and you'll have 2 loops in your code instead of 1.