Home > Back-end >  Combine two dimensional vs one dimensional array in numpy
Combine two dimensional vs one dimensional array in numpy

Time:02-02

I have two numpy arrays like this,

data1 = np.array([[17, 48],
                  [17, 53],
                  [17, 55]])
data2 = np.array([100,200])

I want to combine those arrays by adding 1 at the beginning of the each one.

I tried,

out = []
for i in data1:
    for j in data2:
        out.append([1,i,j])
np.array(out)

#array([[1, array([17, 48]), 100],
#       [1, array([17, 48]), 200],
#       [1, array([17, 53]), 100],
#       [1, array([17, 53]), 200],
#       [1, array([17, 55]), 100],
#       [1, array([17, 55]), 200]], dtype=object)

But the output is not the one I desire. The expected one is like below.

data_desired = np.array([[1,17,48,100],
                         [1,17,48,200],
                         [1,17,53,100],
                         [1,17,53,200],
                         [1,17,55,100],
                         [1,17,55,200]])

By the way, using loop seems also wrong to me. Maybe there exist some other alternatives like broadcasting, newaxis etc?

Thanks in advance!

CodePudding user response:

You can use the unpacking operator * to unpack i. This is probably the easiest fix for your situation.

out = []
for i in data1:
    for j in data2:
        out.append([1,*i,j])
np.array(out)

CodePudding user response:

If speed is relevant and you are going to use large arrays, you shouldn't use loops or growing data structures:

>>> n1 = len(data1)
>>> n2 = len(data2)
>>> result = np.empty_like(data1, shape=(n1*n2, 4))
>>> result[:, 0] = 1
>>> result[:, 1:3] = np.repeat(data1, n2, axis=0)
>>> result[:, 3] = np.repeat(data2[None, :], m1, axis=0).ravel()
>>> result
array([[  1,  17,  48, 100],
       [  1,  17,  48, 200],
       [  1,  17,  53, 100],
       [  1,  17,  53, 200],
       [  1,  17,  55, 100],
       [  1,  17,  55, 200]])

CodePudding user response:

A variant on @aerobiomat's answer, using broadcasting instead of repeat to fill in the data. reshape produces a view, so assignment to it affects res itself. Working this out took some experimenting, so it's not necessarily superior.

In [141]: res = np.ones((6,4),data1.dtype)
In [142]: res.reshape((3,2,4))[:,:,1:3]=data1[:,None,:]
In [143]: res.reshape((3,2,4))[:,:,3]=data2
In [144]: res
Out[144]: 
array([[  1,  17,  48, 100],
       [  1,  17,  48, 200],
       [  1,  17,  53, 100],
       [  1,  17,  53, 200],
       [  1,  17,  55, 100],
       [  1,  17,  55, 200]])

The reshaped array looks like:

In [145]: res.reshape((3,2,4))
Out[145]: 
array([[[  1,  17,  48, 100],
        [  1,  17,  48, 200]],

       [[  1,  17,  53, 100],
        [  1,  17,  53, 200]],

       [[  1,  17,  55, 100],
        [  1,  17,  55, 200]]])
  •  Tags:  
  • Related