Home > Mobile >  Fastest way to duplicate 2D numpy array then insert zeros?
Fastest way to duplicate 2D numpy array then insert zeros?

Time:02-21

I tried looking for this problem extensively on StackOverflow but I couldn't find anything. I am coding some algorithms on a drone that need to be fast so that my system doesn't fail.

I have a set of points, like the following:

In: points = np.array( [[ 0 10 10], [ 4  8  8], [14 14 14], [16 19 19]] )
Out: points: 
 [[ 0 10 10]
 [ 4  8  8]
 [14 14 14]
 [16 19 19]]

I am trying to achieve the following:

new_points: 
 [[ 0 10 10]
 [ 0 10 10]
 [0, 0, 0]
 [0, 0, 0]
 [0, 0, 0]
 [0, 0, 0]
 [0, 0, 0]
 [0, 0, 0]
 [ 4  8  8]
 [ 4  8  8]
 [0, 0, 0]
 [0, 0, 0]
 [0, 0, 0]
 [0, 0, 0]
 [0, 0, 0]
 [0, 0, 0]
 [14 14 14]
 [14 14 14]
 [0, 0, 0]
 [0, 0, 0]
 [0, 0, 0]
 [0, 0, 0]
 [0, 0, 0]
 [0, 0, 0]
 [16 19 19]
 [16 19 19]]

Each point is being repeated once along axis = 0, and then there are 6 (could be any number) rows of zeros being inserted between the points. If it makes it easier, I don't mind if there are zeros after the last point as well.

I tried using np.concatenate(), np.insert(), and np.repeat() to do this, however I could only get a single row of zeros inserted in an undesired location. For example here is what I tried with insert:

In: np.insert(points, np.arange(1,len(points)), 0, axis = 0)
Out: new_points: 
 [[ 0 10 10]
 [ 0  0  0]
 [ 0 10 10]
 [ 0  0  0]
 [ 4  8  8]
 [ 0  0  0]
 [ 4  8  8]
 [ 0  0  0]
 [14 14 14]
 [ 0  0  0]
 [14 14 14]
 [ 0  0  0]
 [16 19 19]
 [ 0  0  0]]

I couldn't get concatenate to be the right shape. This StackOverflow post showed how np.concatenate() was faster, so that's why I tried it. I am trying to use only numpy for this. Any tips?

CodePudding user response:

One way using np.c_ and np.tile:

x,y = points.shape
n1 = 2  # number of times to duplicates the existing rows
n2 = 6  # number of zeros' rows to insert in between

            # n1 times existing data  # n2 times zeros    # to original shape
out = np.c_[np.tile(points, (1,n1)), np.zeros((x, y*n2))].reshape(-1,y)[:-n2]

output:

array([[ 0., 10., 10.],
       [ 0., 10., 10.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 4.,  8.,  8.],
       [ 4.,  8.,  8.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [14., 14., 14.],
       [14., 14., 14.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [16., 19., 19.],
       [16., 19., 19.]])

CodePudding user response:

Create a zero array first and then assign points values to it:

new_points = np.zeros((points.shape[0] * 8 - 6, points.shape[1]))
new_points[::8] = points
new_points[1::8] = points

new_points
array([[ 0., 10., 10.],
       [ 0., 10., 10.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 4.,  8.,  8.],
       [ 4.,  8.,  8.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [14., 14., 14.],
       [14., 14., 14.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [16., 19., 19.],
       [16., 19., 19.]])
  • Related