0

I have an matrix represented by a np array. Here is an example of what I am talking about. You can see it has 3 "vectors" inside of it

x = np.array([[1, 1], [1,2],[2,3]])

[1, 1], [1,2] and [2,3]

The goal is to turn this into a matrix where these vectors are repeated. So the 0th row of said matrix should simply be [1,1] repeated n times. And the 1st row should be [1,2] repeated n times. I believe this would look somewhat like for n=4

xresult = np.array([[[1, 1], [1, 1], [1, 1], [1, 1]],
              [[1, 2], [1, 2], [1, 2], [1, 2]], 
              [[2, 3], [2, 3], [2, 3], [2, 3]]])

And therefore

xresult[0,0] = [1,1]
xresult[0,1] = [1,1]
xresult[0,2] = [1,1]
xresult[1,2] = [1,2]

The goal is of course to do this without loops if possible as that is an obvious but perhaps less elegant/performant solution.

Here are some attempts that do not work

np.tile([x],(2,1))
>>>array([[[1, 1],
        [1, 2],
        [2, 3],
        [1, 1],
        [1, 2],
        [2, 3]]])
np.tile([x],(2,))
>>>array([[[1, 1, 1, 1],
        [1, 2, 1, 2],
        [2, 3, 2, 3]]])
np.append(x,x,axis=0)
>>>array([[1, 1],
       [1, 2],
       [2, 3],
       [1, 1],
       [1, 2],
       [2, 3]])
np.append([x],[x],axis=1)
>>>array([[[1, 1],
        [1, 2],
        [2, 3],
        [1, 1],
        [1, 2],
        [2, 3]]])
np.array([[x],[x]])
>>>array([[[[1, 1],
         [1, 2],
         [2, 3]]],


       [[[1, 1],
         [1, 2],
         [2, 3]]]])

(Some of these were just with n=2 as a goal)

It is worth noting that the ultimate end goal is to take x and y (a similarly crafted array of vectors of the same dimension but not necessarily the same number of vectors

y = np.array([[99,11], [23,44],[33,44], [2, 1], [9, 9]])

And run the procedure on x so that columns of the result are the number of vectors in y. And run a procedure on y that is similar but does this row-wise.

y after this transform would have the following

yresult[0,0] = [99,11]
yresult[1,0] = [22,44]
yresult[2,0] = [33,44]
yresult[2,1] = [33,44]

This way I can subtract the two matrices. The goal is to create a matrix where x'vector index is the row, y'vector index is the row and the element is the difference between these two vectors.

ultimateResult[0,1]=[1,1]-[23,44]=[-22,-43]

Perhaps there is a better way to get this.

J.Doe
  • 1,502
  • 13
  • 47
  • Have you looked at https://stackoverflow.com/questions/1550130/cloning-row-or-column-vectors ? – Mateen Ulhaq Feb 18 '20 at 03:27
  • 1
    `x[:,None].repeat(4,1)` adds a new middle dimension, and replicates the array on that . The equivalent with `tile`: `np.tile(x[:,None],(1,4,1))`. Or `np.stack([x]*4, axis=1) ` – hpaulj Feb 18 '20 at 03:29
  • 1
    `np.repeat(x[:, np.newaxis, :], 4, axis=1)` is one way. You need to create a place for it to repeat. – Mateen Ulhaq Feb 18 '20 at 03:30
  • Both of those work. Could you explain the rationale on the colon and or/np.newaxis usage here. Mostly because I am now trying to sort out the transformation for y here. – J.Doe Feb 18 '20 at 03:32
  • I will use swapaxis for now probably not a too bad plan – J.Doe Feb 18 '20 at 03:38
  • What should the modified `y` look like? Your description isn't clear. Also, there's also ways to `broadcast` to avoid extra memory usage from repeating. – Mateen Ulhaq Feb 18 '20 at 03:43
  • @MateenUlhaq I have updated question with examples for y – J.Doe Feb 18 '20 at 03:48
  • Would love to hear if you have a good broadcasting solution because you are right this repetition would ideally not take up any more memory. Or perhaps that is worse for caching? I would have to experiment between the two options. – J.Doe Feb 18 '20 at 03:49
  • The descriptions for `xresult` and `yresult` are the same. But I'm guessing you want `np.repeat(y[np.newaxis, :, :], 4, axis=0)`. Overall, what you're trying to do is almost the same thing as a "Cartesian product". – Mateen Ulhaq Feb 18 '20 at 03:59

0 Answers0