Home > Back-end >  Python: ways to vectorize "apply a power function with random power to each row in NumPy array&
Python: ways to vectorize "apply a power function with random power to each row in NumPy array&

Time:06-07

I would like to find efficient ways to do the following operation:

  1. I have a vector of known values, which will be the first row in the following array mentioned.
  2. I would like to create an array. For each row other than the first row, it is essentially the first row applied with a power function with a random power.

For example, we have a 3x2 array. The first row is known: [0,1,2].

Then for the second row, generate a random power, let it be 0.5, then the second row is: [0^0.5,1^0.5,2^0.5].

Now for the third row, generate a random power, let it be 3, then the third row is: [0^3,1^3,2^3].

I can do this easily with for loop. But I am wondering if there is any efficient way to vectorize it (or just efficient enough without vectorization).

Sample code:

beta=np.zeros((3,1000 1))
beta[0]=np.append(0,np.random.uniform(0,1,1000))

for i in range(1,3,1):
    p=np.random.uniform(0,2)
    beta[i]= beta[0]**p

Thank you so much for your help in advance!

CodePudding user response:

Broadcasting to the rescue:

In [2]: beta = np.array([0, 1, 2])

In [3]: lo, hi, num_rows_desired = 0, 3, 3

In [4]: exps = np.random.uniform(lo, hi, num_rows_desired)

In [5]: exps[0] = 1  # Set the first 'power' to 1

In [6]: beta ** exps[:, None]
Out[6]:
array([[0.        , 1.        , 2.        ],
       [0.        , 1.        , 1.41421356],
       [0.        , 1.        , 8.        ]])

Where lo and hi are the bounds for your uniformly distributed exponents, and num_rows_desired is however many exponents you want to apply to beta (which will result in that many rows).

This is probably the way you want to do this, since creating your entire beta array in memory is wasteful. Simply generate your initial row vector for beta and let broadcasting do the work for you.

  • Related