Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Numpy repeat array along new axis

What’s the best/most performant way?

with x being the array and n being the number of times i want it repeated:

np.repeat(x[None,...], n, axis=0)

or

ones = [1] * len(x.shape)
np.tile(x, tuple(n, *ones))

note that for a known array size, the latter becomes simple:

np.tile(x, (n, 1, 1))  # x is 2D
like image 679
flying sheep Avatar asked Dec 21 '14 19:12

flying sheep


1 Answers

Part of the code for np.tile is:

for i, nrep in enumerate(tup):
    if nrep!=1:
        c = c.reshape(-1, n).repeat(nrep, 0)

In other words, it does repeat on each of the axis with more than 1 repeat. It is, effect, a generalization of repeat to multiple axes.

So I'd expect timings to be similar, though plain repeat will have less Python overhead. repeat is compiled. (a few simple tests confirm this - repeat is 2x faster for small arrays, slightly faster for large ones).

p.s. The x[None,...] step is virtually costless. And due to broadcasting it might be all you need.


p.s.s. There is an even faster way of doing this repeat, using np.lib.index_tricks.as_strided. For a (20,50) shaped x,

as_strided(x,shape=(n,20,50),strides=(0,200,4))

np.broadcast_arrays also uses as_strided. So this produces the same thing:

np.broadcast_arrays(np.ones((n,1,1)),x)[1] 

But to be honest, this is just an elaboration on broadcasting, not a true repeat. The data hasn't been replicated. The same values are just used n times.

Broadcasting can be used to populate the full array, but the timings are the same as for repeat. That may be what repeat is doing under the hood.

z = np.empty((300,20,50),dtype=int)
z[:] = x[None,...]
like image 197
hpaulj Avatar answered Oct 08 '22 08:10

hpaulj