Python: Insert 2D array into 3D NumPy array along different rows Python: Insert 2D array into 3D NumPy array along different rows numpy numpy

Python: Insert 2D array into 3D NumPy array along different rows


Here's one based on array-assignment and masking -

from skimage.util.shape import view_as_windowsdef insert_into_arr(arr, row_number_before_insertion, val_to_insert):    ma,na,ra = arr.shape    L = len(val_to_insert)    N = len(row_number_before_insertion)    out = np.zeros((ma,na+L,ra),dtype=arr.dtype)    mask = np.ones(out.shape, dtype=bool)    w = view_as_windows(out,(1,L,1))[...,0,:,0]    w[np.arange(N), row_number_before_insertion] = val_to_insert.T    wm = view_as_windows(mask,(1,L,1))[...,0,:,0]    wm[np.arange(N), row_number_before_insertion] = 0    out[mask] = arr.ravel()    return out

Sample run -

In [44]: arrOut[44]: array([[[ 0,  1],        [ 2,  3],        [ 4,  5]],       [[ 6,  7],        [ 8,  9],        [10, 11]]])In [45]: row_number_before_insertionOut[45]: array([1, 2])In [46]: val_to_insertOut[46]: array([[784, 659],       [729, 292],       [935, 863]])In [47]: insert_into_arr(arr, row_number_before_insertion, val_to_insert)Out[47]: array([[[  0,   1],        [784, 659],        [729, 292],        [935, 863],        [  2,   3],        [  4,   5]],       [[  6,   7],        [  8,   9],        [784, 659],        [729, 292],        [935, 863],        [ 10,  11]]])

Another with repeat and masking -

def insert_into_arr_v2(arr, row_number_before_insertion, val_to_insert):      ma,na,ra = arr.shape    r = row_number_before_insertion    L = len(val_to_insert)    M = na+L    out = np.zeros((ma,na+L,ra),dtype=arr.dtype)    idx = ((r + M*np.arange(len(r)))[:,None] + np.arange(L)).ravel()    out.reshape(-1,ra)[idx] =np.repeat(val_to_insert[None],ma,axis=0).reshape(-1,ra)    mask = np.isin(np.arange(ma*(na+L)),idx, invert=True)    out.reshape(-1,ra)[mask] = arr.reshape(-1,ra)    return out


Here's a solution using vstack:

def insert_into_arr(arr, row_number_before_insertion, val_to_insert):    num_slices, num_rows, num_cols = arr.shape    arr_expanded = np.zeros((num_slices, num_rows + val_to_insert.shape[0], num_cols))    for i in range(num_slices):        if row_number_before_insertion[i] == 0:            arr_expanded[i, :, :] = np.vstack((val_to_insert, arr[i, :, :]))        else:            arr_expanded[i, :, :] = np.vstack((arr[i, 0:row_number_before_insertion[i], :], val_to_insert, arr[i, row_number_before_insertion [i]:, :]))    return arr_expandedarr = np.arange(12).reshape(2, 3, 2)row_number_before_insertion = [1, 2]val_to_insert = (np.ones(4) * 100).reshape(2,2)arr_expanded = insert_into_arr(arr, row_number_before_insertion, val_to_insert)arr_expandedarray([[[   0.,    1.],        [ 100.,  100.],        [ 100.,  100.],        [   2.,    3.],        [   4.,    5.]],       [[   6.,    7.],        [   8.,    9.],        [ 100.,  100.],        [ 100.,  100.],        [  10.,   11.]]])