简体   繁体   中英

copy from two multidimensional numpy array to another with different shape

I have two numpy arrays of the following shape:

print(a.shape) -> (100, 20, 3, 3)
print(b.shape) -> (100, 3)

Array a is empty, as I just need this predefined shape, I created it with:

a = numpy.empty(shape=(100, 20, 3, 3))

Now I would like to copy data from array b to array a so that the second and third dimension of array a gets filled with the same 3 values of the corresponding row of array b .

Let me try to make it a bit clearer: Array b contains 100 rows ( 100 , 3) and each row holds three values (100, 3 ). Now every row of array a ( 100 , 20, 3, 3) should also hold the same three values in the last dimension (100, 20, 3, 3 ), while those three values stay the same for the second and third dimension (100, 20 , 3 , 3) for the same row ( 100 , 20, 3, 3).

How can I copy the data as described without using loops? I just can not get it done but there must be an easy solution for this.

You can use repeat along axis . You also do not need to predefine a . I would also suggest NOT to use broadcast_to since it returns readonly view and memory is shared among elements:

a = np.repeat(b[:,None,None,:], 20, 1) #adds dimensions 1 and 2 and repeats 20 times along axis 1
a = np.repeat(a, 3, 2) #repeats 3 times along axis 2

Smaller example:

b = np.arange(2*3).reshape(2,3)
#[[0 1 2]
# [3 4 5]]
a = np.repeat(b[:,None,None,:], 2, 1) 
a = np.repeat(a, 3, 2) 
#shape(2,2,3,3)
[[[[0 1 2]
   [0 1 2]
   [0 1 2]]

  [[0 1 2]
   [0 1 2]
   [0 1 2]]]


 [[[3 4 5]
   [3 4 5]
   [3 4 5]]

  [[3 4 5]
   [3 4 5]
   [3 4 5]]]]

We can make use of np.broadcast_to .

If you are okay with a view -

np.broadcast_to(b[:,None, None, :], (100, 2, 3, 3))

If you need an output with its own memory space, simply append with .copy() .

If you want to save on memory and fill into already defined array, a :

a[:] = b[:,None,None,:]

Note that we can skip the trailing : s.

Timings :

In [20]: b = np.random.rand(100, 3)

In [21]: %timeit np.broadcast_to(b[:,None, None, :], (100, 2, 3, 3))
5.93 µs ± 64.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [22]: %timeit np.broadcast_to(b[:,None, None, :], (100, 2, 3, 3)).copy()
11.4 µs ± 56.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [23]: %timeit np.repeat(np.repeat(b[:,None,None,:], 20, 1), 3, 2)
39.3 µs ± 147 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM