0

I have some arrays

x = np.empty(3)
y = np.empty(3)

for i in range(len(x)):
    x[i] = float(i)
    y[i] = float(i + 3)

print(x, y)

Output ~ [0., 1., 2.], [3., 4., 5.]

I would like to be able to get this instead

[0., 3., 1., 4., 2., 5.]

How can I do that?

I tried zip, but that appears to create an iterable class, not a new instance of the objects passed to it.

I tried np.concatenate(), but it didn't appear to have a "stride" option, which is along the lines of what I'm probably looking for. (No luck with a search however)

FreelanceConsultant
  • 13,167
  • 27
  • 115
  • 225

3 Answers3

1

You can use np.stack((x, y), axis=1).ravel().

a_guest
  • 34,165
  • 12
  • 64
  • 118
0

Using zip:

np.ravel(list(zip(x,y)))

Output:

[0. 3. 1. 4. 2. 5.]

You can unpack zip by putting it in list constructor then flatten it with numpy.ravel.

Grzegorz Skibinski
  • 12,624
  • 2
  • 11
  • 34
0

Making your arrays without iteration:

In [157]: x = np.arange(3); y = np.arange(3, 6)                                 
In [158]: x, y                                                                  
Out[158]: (array([0, 1, 2]), array([3, 4, 5]))

We can join them into a 2d array with

In [159]: np.array((x,y))         # np.vstack also works                                              
Out[159]: 
array([[0, 1, 2],
       [3, 4, 5]])

We can then ravel or flatten the 2d array. By specifying fortran order, we get the interleaving that you want:

In [160]: np.array((x,y)).ravel(order='F')                                      
Out[160]: array([0, 3, 1, 4, 2, 5])

With the default 'c' order:

In [161]: np.array((x,y)).ravel()                                               
Out[161]: array([0, 1, 2, 3, 4, 5])

Another way is to stack them as columns:

In [162]: np.stack((x,y),axis=1)                                                
Out[162]: 
array([[0, 3],
       [1, 4],
       [2, 5]])
In [163]: np.stack((x,y),axis=1).ravel()                                        
Out[163]: array([0, 3, 1, 4, 2, 5])

Making a list from the zip:

In [164]: list(zip(x,y))                                                        
Out[164]: [(0, 3), (1, 4), (2, 5)]

This list is group; there are ways of flattening such a such list. But we could also use extend to join the tuples to a list:

In [165]: alist = []                                                            
In [166]: for i,j in zip(x,y): alist.extend((i,j))                              
In [167]: alist                                                                 
Out[167]: [0, 3, 1, 4, 2, 5]

vstack and stack are variations on concatenate, adjust the array dimensions in different ways and then joining on different axes.

In [169]: np.concatenate((x[:,None], y[:,None]),axis=1)                         
Out[169]: 
array([[0, 3],
       [1, 4],
       [2, 5]])

another way - join the rows, and transpose to columns:

In [170]: np.array((x,y)).T                                                     
Out[170]: 
array([[0, 3],
       [1, 4],
       [2, 5]])

yet another way - insert the arrays into a target, specifying an every-other stride:

In [171]: res = np.zeros(6,int)                                                 
In [172]: res[::2] = x; res[1::2] = y                                           
In [173]: res                                                                   
Out[173]: array([0, 3, 1, 4, 2, 5])
hpaulj
  • 221,503
  • 14
  • 230
  • 353