Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to repeat elements of an array along two axes?

Tags:

I want to repeat elements of an array along axis 0 and axis 1 for M and N times respectively:

import numpy as np  a = np.arange(12).reshape(3, 4) b = a.repeat(2, 0).repeat(2, 1) print(b)  [[ 0  0  1  1  2  2  3  3]  [ 0  0  1  1  2  2  3  3]  [ 4  4  5  5  6  6  7  7]  [ 4  4  5  5  6  6  7  7]  [ 8  8  9  9 10 10 11 11]  [ 8  8  9  9 10 10 11 11]] 

This works, but I want to know are there better methods without create a temporary array.

like image 831
HYRY Avatar asked Oct 05 '11 04:10

HYRY


People also ask

How do you repeat an element in an array?

The repeat() function is used to repeat elements of an array. Input array. The number of repetitions for each element. repeats is broadcasted to fit the shape of the given axis.

How do you repeat an element in an array in Python?

In Python, if you want to repeat the elements multiple times in the NumPy array then you can use the numpy. repeat() function. In Python, this method is available in the NumPy module and this function is used to return the numpy array of the repeated items along with axis such as 0 and 1.

How does NP repeat work?

The NumPy repeat function essentially repeats the numbers inside of an array. It repeats the individual elements of an array. Having said that, the behavior of NumPy repeat is a little hard to understand sometimes.

How do you duplicate an element in an array in NumPy?

To copy array data to another using Python Numpy library, you can use numpy. ndarray. copy() function.


2 Answers

You could use the Kronecker product, see numpy.kron:

>>> a = np.arange(12).reshape(3,4) >>> print(np.kron(a, np.ones((2,2), dtype=a.dtype))) [[ 0  0  1  1  2  2  3  3]  [ 0  0  1  1  2  2  3  3]  [ 4  4  5  5  6  6  7  7]  [ 4  4  5  5  6  6  7  7]  [ 8  8  9  9 10 10 11 11]  [ 8  8  9  9 10 10 11 11]] 

Your original method is OK too, though!

like image 73
wim Avatar answered Sep 22 '22 02:09

wim


You can make use of np.broadcast_to here:

def broadcast_tile(a, h, w):     x, y = a.shape     m, n = x * h, y * w     return np.broadcast_to(         a.reshape(x, 1, y, 1), (x, h, y, w)     ).reshape(m, n)  broadcast_tile(a, 2, 2) 

array([[ 0,  0,  1,  1,  2,  2,  3,  3],        [ 0,  0,  1,  1,  2,  2,  3,  3],        [ 4,  4,  5,  5,  6,  6,  7,  7],        [ 4,  4,  5,  5,  6,  6,  7,  7],        [ 8,  8,  9,  9, 10, 10, 11, 11],        [ 8,  8,  9,  9, 10, 10, 11, 11]]) 

Performance


Functions

def chris(a, h, w):     x, y = a.shape     m, n = x * h, y * w     return np.broadcast_to(         a.reshape(x, 1, y, 1), (x, h, y, w)     ).reshape(m, n)  def alex_riley(a, b0, b1):     r, c = a.shape     rs, cs = a.strides     x = np.lib.stride_tricks.as_strided(a, (r, b0, c, b1), (rs, 0, cs, 0))     return x.reshape(r*b0, c*b1)  def paul_panzer(a, b0, b1):     r, c = a.shape     out = np.empty((r, b0, c, b1), a.dtype)     out[...] = a[:, None, :, None]     return out.reshape(r*b0, c*b1)  def wim(a, h, w):     return np.kron(a, np.ones((h,w), dtype=a.dtype)) 

Setup

import numpy as np import pandas as pd from timeit import timeit  res = pd.DataFrame(        index=['chris', 'alex_riley', 'paul_panzer', 'wim'],        columns=[5, 10, 20, 50, 100, 500, 1000],        dtype=float )  a = np.arange(100).reshape((10,10))  for f in res.index:     for c in res.columns:         h = w = c         stmt = '{}(a, h, w)'.format(f)         setp = 'from __main__ import h, w, a, {}'.format(f)         res.at[f, c] = timeit(stmt, setp, number=50) 

Output

enter image description here

like image 20
user3483203 Avatar answered Sep 23 '22 02:09

user3483203