1

I have two numpy arrays current_index which I am trying to fill, and time_to_maturity which has various times. I want to fill current_index uniformly with varying boundaries.

I see two ways to do this, do you know why both works. The first one makes sense to me:

for i in range(len(current_index)):
current_index[i] =  np.random.uniform(low=900.0*(1 - .2 *((756 - time_to_maturity[i])/252)), high=1000*(1 + .2 *((756 - time_to_maturity[i])/252)))

I know this is not the ideal way, and I want to vectorize this operation. I tried something else which seemed to work but I do not know why.

current_index =  np.random.uniform(low=900*(1 - .2 *((756 - time_to_maturity)/252)), high=1000**(1 + .2 *((756 - time_to_maturity)/252)))

Why does the second way work? I am setting the whole array to a single value with the upper and lower bounds as the whole array? I did not specify the output shape, so I am curious as to why this works.

Thank you in advanced.

3
  • Are you familiar with NumPy's broadcasting? Commented Jan 25, 2022 at 16:28
  • I just gave it a read and I am not sure how that applied to the second formula. Commented Jan 25, 2022 at 17:13
  • Ah, you're right, broadcasting isn't really the important concept there. I'll add an answer with an explanation. Commented Jan 25, 2022 at 18:25

1 Answer 1

1

"Why does the second way work?"

numpy.random.uniform (and the newer--and preferred--method numpy.random.Generator.uniform) accepts arrays for its argument. The function acts elementwise on the arrays (and broadcasts the arrays if they are not all the same shape). So, for example, if you want to generate three random values, one between 0 and 0.5, another between 1 and 100, and a third between 10 and 20, you can use low=[0, 1, 10] and high=[0.5, 100, 20], and uniform will generate a random value for the intervals [0, 0.5], [1, 100] and [10, 20]. E.g.

In [76]: rng = np.random.default_rng()

In [77]: rng.uniform([0, 1, 10], [0.5, 100, 20])
Out[77]: array([ 0.17395605, 44.44896554, 18.5859792 ])

In your case, you have an array time_to_maturity that you use to compute the low and high arguments. The expressions that you used corresond to the literal values [0, 1, 10] and [0.5, 100, 20] that I used in the simple example.

Let's say time_to_maturity is [450, 500, 600]:

In [99]: time_to_maturity = np.array([450, 500, 600])

The expressions that you computed for the low and high values for uniform are:

In [100]: low = 900*(1 - .2 *((756 - time_to_maturity)/252))

In [101]: high = 1000**(1 + .2 *((756 - time_to_maturity)/252))

Each of these is now an array of length 3:

In [102]: low
Out[102]: array([681.42857143, 717.14285714, 788.57142857])

In [103]: high
Out[103]: array([5352.68182285, 4069.33842717, 2351.95263507])

When you pass these to uniform it acts the same way it did with my simple example above; that is, it generates three random values, one for each interval [681.42857143, 5352.68182285], [717.14285714, 4069.33842717] and [788.57142857, 2351.95263507]:

In [104]: rng.uniform(low=low, high=high)
Out[104]: array([2413.52004774, 3823.84034721, 1795.17805683])
Sign up to request clarification or add additional context in comments.

1 Comment

Warren, this is a great answer thank you so much. I did just catch that error in my first piece of code. so thank you for that. I will change in this problem. I do not have enough points on this website to upvote your solution. But I want to say thanks for your help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.