cs95
cs95

Reputation: 402323

An elegant way of inserting a numpy matrix into another

I have a requirement where I have 2 2D numpy arrays, and I would like to combine them in a specific manner:

x = [[0, 1, 2],
     [3, 4, 5],
     [6, 7, 8]]
      |  |  |
      0  1  2

y = [[10, 11, 12],
     [13, 14, 15],
     [16, 17, 18]]
      |   |    |
      3   4    5

 x op y = [ 0 3 1 4 2 5 ] (in terms of the columns)

In other words,

The combination of x and y should look something like this:

      [[  0.,  10.,   1.,  11.,   2.,  12.],
       [  3.,  13.,   4.,  14.,   5.,  15.],
       [  6.,  16.,   7.,  17.,   8.,  18.]]

Where I alternately combine the columns of each individual array to form the final 2D array. I have come up with one way of doing so, but it is rather ugly. Here's my code:

x = np.arange(9).reshape(3, 3)
y = np.arange(start=10, stop=19).reshape(3, 3)
>>> a = np.zeros((6, 3)) # create a 2D array where num_rows(a) = num_cols(x) + num_cols(y)
>>> a[: : 2] = x.T
>>> a[1: : 2] = y.T
>>> a.T
array([[  0.,  10.,   1.,  11.,   2.,  12.],
       [  3.,  13.,   4.,  14.,   5.,  15.],
       [  6.,  16.,   7.,  17.,   8.,  18.]])

As you can see, this is a very ugly sequence of operations. Furthermore, things become even more cumbersome in higher dimensions. For example, if you have x and y to be [3 x 3 x 3], then this operation has to be repeated in each dimension. So I'd probably have to tackle this with a loop.

Is there a simpler way around this?

Thanks.

Upvotes: 0

Views: 438

Answers (2)

Bremsstrahlung
Bremsstrahlung

Reputation: 730

Here is a compact way to write it with a loop, it might be generalizable to higher dimension arrays with a little work:

    x = np.array([[0,1,2], [3,4,5], [6,7,8]])
    y = np.array([[10,11,12], [13,14,15], [16,17,18]])
    z = np.zeros((3,6))
    for i in xrange(3):
        z[i] = np.vstack((x.T[i],y.T[i])).reshape((-1,),order='F')

Upvotes: 0

hpaulj
hpaulj

Reputation: 231355

In [524]: x=np.arange(9).reshape(3,3)
In [525]: y=np.arange(10,19).reshape(3,3)

This doesn't look at all ugly to me (one liners are over rated):

In [526]: a = np.zeros((3,6),int)
....
In [528]: a[:,::2]=x
In [529]: a[:,1::2]=y
In [530]: a
Out[530]: 
array([[ 0, 10,  1, 11,  2, 12],
       [ 3, 13,  4, 14,  5, 15],
       [ 6, 16,  7, 17,  8, 18]])

still if you want a one liner, this might do:

In [535]: np.stack((x.T,y.T),axis=1).reshape(6,3).T
Out[535]: 
array([[ 0, 10,  1, 11,  2, 12],
       [ 3, 13,  4, 14,  5, 15],
       [ 6, 16,  7, 17,  8, 18]])

The idea on this last was to combine the arrays on a new dimension, and reshape is some way other. I found it by trial and error.

and with another trial:

In [539]: np.stack((x,y),2).reshape(3,6)
Out[539]: 
array([[ 0, 10,  1, 11,  2, 12],
       [ 3, 13,  4, 14,  5, 15],
       [ 6, 16,  7, 17,  8, 18]])

Upvotes: 1

Related Questions