Ha! I knew it had to be possible! Thanks Derek. So for and N = 2 (now on my laptop):
In [70]: M = 1200 In [69]: N = 2 In [71]: a = np.random.randint(0, 255, (M**2)).reshape(M,-1) In [76]: timeit np.rollaxis(np.tile(a, N**2).reshape(M,N,-1), 2, 1).reshape(M*N,-1) 10 loops, best of 3: 99.1 ms per loop In [78]: timeit a.repeat(2, axis=0).repeat(2, axis=1) 10 loops, best of 3: 85.6 ms per loop In [79]: timeit np.kron(a, np.ones((2,2), 'uint8')) 1 loops, best of 3: 521 ms per loop It turns out np.kron and repeat are pretty straightforward for multi-dimensional data too - scaling or stretching a stacked array representing pixel data over time, for example. Nothing changes for np.kron - it handles the additional dimensionality by itself. With repeat you just tell it to operate on the last two dimensions. So to sum up: 1) np.kron is cool for the simplicity of the code and simple scaling to N dimensions. It's also handy if you want to scale the array elements themselves too. 2) repeat() along the last N axes is a bit more intuitive (i.e. less magical) to me and has a better performance profile. 3) Derek's reshape/rolling solution is almost as fast but it gives me a headache trying to visualize what it's actually doing. I don't want to think about adding another dimension ... Thanks for the help folks. Here's scaling of a hypothetical time series (i.e. 3 axes), where each sub-array represents a month. In [26]: print a [[[1 2] [3 4]] [[1 2] [3 4]] [[1 2] [3 4]]] In [27]: np.kron(a, np.ones((2,2), dtype='uint8')) Out[27]: array([[[1, 1, 2, 2], [1, 1, 2, 2], [3, 3, 4, 4], [3, 3, 4, 4]], [[1, 1, 2, 2], [1, 1, 2, 2], [3, 3, 4, 4], [3, 3, 4, 4]], [[1, 1, 2, 2], [1, 1, 2, 2], [3, 3, 4, 4], [3, 3, 4, 4]]]) In [64]: a.repeat(2, axis=1).repeat(2, axis=2) Out[64]: array([[[1, 1, 2, 2], [1, 1, 2, 2], [3, 3, 4, 4], [3, 3, 4, 4]], [[1, 1, 2, 2], [1, 1, 2, 2], [3, 3, 4, 4], [3, 3, 4, 4]], [[1, 1, 2, 2], [1, 1, 2, 2], [3, 3, 4, 4], [3, 3, 4, 4]]]) On Dec. 3, 2011, at 12:50PM, Derek Homeier wrote: > On 03.12.2011, at 6:22PM, Robin Kraft wrote: > > > That does repeat the elements, but doesn't get them into the desired order. > > > > In [4]: print a > > [[1 2] > > [3 4]] > > > > In [7]: np.tile(a, 4) > > Out[7]: > > array([[1, 2, 1, 2, 1, 2, 1, 2], > > [3, 4, 3, 4, 3, 4, 3, 4]]) > > > > In [8]: np.tile(a, 4).reshape(4,4) > > Out[8]: > > array([[1, 2, 1, 2], > > [1, 2, 1, 2], > > [3, 4, 3, 4], > > [3, 4, 3, 4]]) > > > > It's close, but I want to repeat the elements along the two axes, > > effectively stretching it by the lower right corner: > > > > array([[1, 1, 2, 2], > > [1, 1, 2, 2], > > [3, 3, 4, 4], > > [3, 3, 4, 4]]) > > > > It would take some more reshaping/axis rolling to get there, but it seems > > doable. > > > > Anyone know what combination of manipulations would work with the result of > > np.tile? > > > Rolling was the keyword: > > np.rollaxis(np.tile(a, 4).reshape(2,2,-1), 2, 1).reshape(4,4)) > [[1 1 2 2] > [1 1 2 2] > [3 3 4 4] > [3 3 4 4]] > > I leave the generalisation and timing up to you, but it seems for > a = np.arange(M**2).reshape(M,-1) > > np.rollaxis(np.tile(a, N**2).reshape(M,N,-1), 2, 1).reshape(M*N,-1) > > should do the trick. > > Cheers, > Derek
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion