简体   繁体   中英

Repeating a Numpy array to match dimension of another array

I'd like to repeat an array along multiple dimensions, such that it matches the dimensions of another array.

For example, lets put:

import numpy as np

a = np.arange(300)
b = np.zeros((300, 10, 20, 40, 50))

I'd like to expand a such that it matches the dimensions of b , considering than be can have an arbitrary number of dimensions of arbitrary length.

For now, the only thing I can do is a loop over the dimensions like:

c = np.copy(a)
for axis, length in enumerate(b.shape[1:]):
  c = np.repeat(c[..., None], length, axis + 1)

But it is rather inefficient for a large number of dimensions...

reshape and expand_dims can make an array that will broadcast like a b shaped array

tile can expand that. Check the code, but I think it does repeated repeats as you do:

d=np.tile(np.expand_dims(a,[1,2,3,4]),(1,)+b.shape[1:])

Another way to expand the array to full size, but without the full memory use is:

w = np.broadcast_to(np.expand_dims(a,[1,2,3,4]),b.shape)

w should have the same shape, but strides will be (8, 0, 0, 0, 0) , compared to (3200000, 320000, 16000, 400, 8) for b or c .

But making w.copy() will take nearly as long making c or d , because it has to make the full Gb array.

One option is to reshape a so it can be broadcasted against b , and then assign values to target array inplace:

c = np.zeros(b.shape)
c[:] = a.reshape(b.shape[:1] + (1,) * (len(b.shape) - 1))

Or use np.expand_dims to reshape:

c[:] = np.expand_dims(a, axis=tuple(range(1, len(b.shape))))

You could use np.empty_like together with np.copyto

c = np.emtpy_like(b)
np.copyto(c.T,a)

#check:
(c == a[:,None,None,None,None]).all()
# True

Or, if you want to retain a 's dtype:

c = np.empty(b.shape,a.dtype)
# etc.

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