2

I want to add a new row to a numpy 2d-array, say if array 1 has dimensions of (2, 5) and array-2 is a kind of row (which has 3 values or cols) of shape (3,) my resultant array should look like (3, 10) and the last two indices in 3rd row should be NA's.

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

arr2 = array([3, 1, 5])

after some join or concat operation

arr1_arr2 = array([[9, 4, 2, 6, 7],
                   [8, 5, 4, 1, 3], 
                   [3, 1, 5, np.nan, np.nan]])

I have tried numpy append concat functions but they dont work this way.

JAbr
  • 312
  • 2
  • 12
  • 1
    Seems relevant - https://stackoverflow.com/questions/40569220/efficiently-convert-uneven-list-of-lists-to-minimal-containing-array-padded-with – Divakar Apr 24 '19 at 08:48

1 Answers1

2

You can only concatenate arrays of the same number of dimensions (this can be resolved by broadcasting) and the same number of elements except for the concatenating axis.

Thus you need to append/concatenate an empty array of the correct shape and fill it with the values of arr2 afterwards.

# concatenate an array of the correct shape filled with np.nan
arr1_arr2 = np.concatenate((arr1, np.full((1, arr1.shape[1]), np.nan)))
# fill concatenated row with values from arr2
arr1_arr2[-1, :3] = arr2

But in general it is always good advice, NOT to append/concatenate etc. arrays. If it is possible, try to guess the correct shape of the final array in advance and create an empty array (or filled with np.nan) of the final shape, which will be filled in the process. For example:

arr1_arr2 = np.full((3, 5), np.nan)
arr1_arr2[:-1, :] = arr1
arr1_arr2[-1, :arr2.shape[0]] = arr2

If it is only one appending/concatenating operation and it is not performance critical, it is ok to concat/append, otherwise a full preallocation in advance should be preferred.

If many arrays shall be concatenated and all arrays to concatenate have the same shape, this will be the best way to do it:

arr1 = np.array([[9, 4, 2, 6, 7],
                 [8, 5, 4, 1, 3]])
# some arrays to concatenate:
arr2 = np.array([3, 1, 5])
arr3 = np.array([5, 7, 9])
arr4 = np.array([54, 1, 99])
# make array of all arrays to concatenate:
arrs_to_concat = np.vstack((arr2, arr3, arr4))
# preallocate result array filled with nan
arr1_arr2 = np.full((arr1.shape[0] + arrs_to_concat.shape[0], 5), np.nan)
# fill with values:
arr1_arr2[:arr1.shape[0], :] = arr1
arr1_arr2[arr1.shape[0]:, :arrs_to_concat.shape[1]] = arrs_to_concat

Performance-wise it may be a good idea for large arrays to use np.empty for preallocating the final array and filling only the remaining shape with np.nan.

JE_Muc
  • 5,403
  • 2
  • 26
  • 41
  • 1
    So, if i have more arrays to concat i can create a big matrix of nan and then just fill it up. Thanks for the effort!! – JAbr Apr 24 '19 at 08:41
  • I added some more information about having many arrays. Do all of the arrays to concat have the same shape? – JE_Muc Apr 24 '19 at 08:45
  • each ahving different shape but those are 1d array to add to this matrix. – JAbr Apr 24 '19 at 08:56
  • Thanks again Scotty! really a very nice answer and community support example. I really appreciate. – JAbr Apr 24 '19 at 08:58
  • You are welcome! Each having a different shape makes concatenating more difficult. I guess you'll have to stick with my first or second solution. – JE_Muc Apr 24 '19 at 09:00
  • 1
    yeah, i am creating a matrix with all na's and then filling it up, its easy – JAbr Apr 24 '19 at 09:14