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.
CodePudding user response:
"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])
