How to insert extra rows and columns at desired location in a matrix ( python )?

Viewed 93

I was running a loop, from where I obtained ( 4 by 4) arrays, and now I want to insert zeros at certain locations in these arrays and turn them into (6 by 6) arrays.

I want to add zeros in third and sixth row , and also 3rd and sixth column

a_obtained = np.array( [[1,     2,   3,    4   ],
                        [5,     6,   7,    8   ],
                        [9,    10,   11,  12   ],
                        [13,   14,   15,   16  ]])

I tried going through np.vstack, np.hstack, but I am not able to place the zeros at specified locations.

a_desired = result = np.array([[1,     2,  0,   3,    4,   0 ],
                               [5,     6,  0,   7,    8,   0 ],
                               [0,     0,  0,   0,    0,   0 ],
                               [9,    10,  0,   11,  12,   0 ],
                               [13,   14,  0,   15,   6,   0 ],
                               [0,     0,  0,   0,    0,   0 ]])
3 Answers

Using np.insert:

import numpy as np
a_obtained = np.array( [[1,     2,   3,    4   ],
                        [5,     6,   7,    8   ],
                        [9,    10,   11,  12   ],
                        [13,   14,   15,   16  ]])
                        
new_row = np.zeros(4)
a_obtained = np.insert(a_obtained, [3, 4], [new_row], axis= 0)
print(a_obtained)

If we have the desired columns indices, it can be done by np.insert as:

desired_cols_ids = np.array([2, 4], dtype=np.int64)

zero_arr_row = np.zeros((1, a_obtained.shape[1]))
# [[0. 0. 0. 0.]]

a_obtained = np.insert(a_obtained, desired_cols_ids, zero_arr_row, axis=0)
# [[ 1  2  3  4]
#  [ 5  6  7  8]
#  [ 0  0  0  0]
#  [ 9 10 11 12]
#  [13 14 15 16]
#  [ 0  0  0  0]]

zero_arr_col = np.zeros((a_obtained.shape[0], 1))
# [[0.]
#  [0.]
#  [0.]
#  [0.]
#  [0.]
#  [0.]]

a_obtained = np.insert(a_obtained, desired_cols_ids, zero_arr_col, axis=1)
# [[ 1  2  0  3  4  0]
#  [ 5  6  0  7  8  0]
#  [ 0  0  0  0  0  0]
#  [ 9 10  0 11 12  0]
#  [13 14  0 15 16  0]
#  [ 0  0  0  0  0  0]]

For a little explanation, at first, we insert into the array rows (so it is modified) and then insert into the columns of the modified array.

np.insert is relatively easy to use for this task, but internally it uses a variety of methods, depending on the insert specifications. For this case I suspect it does something like the following:

Start with a "blank" array:

In [51]: res = np.zeros((6,6),a_obtained.dtype)

Create a boolean mask of where we want to add rows and columns. Here I can do both rows and columns at once (rather than with 2 insert calls):

In [52]: mask = res.astype(bool)
In [53]: mask[[2,5]] = True
In [54]: mask[:,[2,5]] = True
In [55]: mask
Out[55]: 
array([[False, False,  True, False, False,  True],
       [False, False,  True, False, False,  True],
       [ True,  True,  True,  True,  True,  True],
       [False, False,  True, False, False,  True],
       [False, False,  True, False, False,  True],
       [ True,  True,  True,  True,  True,  True]])

Then just add the original values. Boolean masking selects a "flat" array, so a_obtained has to be flattened as well. Otherwise the insert is straight forward.

In [56]: res[~mask] = a_obtained.ravel()
In [57]: res
Out[57]: 
array([[ 1,  2,  0,  3,  4,  0],
       [ 5,  6,  0,  7,  8,  0],
       [ 0,  0,  0,  0,  0,  0],
       [ 9, 10,  0, 11, 12,  0],
       [13, 14,  0, 15, 16,  0],
       [ 0,  0,  0,  0,  0,  0]])
Related