Home > Blockchain >  Monte Carlo Simulation with multiple distributions in each loop
Monte Carlo Simulation with multiple distributions in each loop

Time:10-17

I have an array of NaNs 10 columns wide and 5 rows long.

I have a 5x3 array of poisson random number generations. This represents 5 runs of each A, B, and C, where each column has a different lambda value for the poisson distribution.

    A  B  C
   [1, 1, 2,
    1, 2, 2,
    2, 1, 4,
    1, 2, 3,
    0, 1, 2]

Each row represents the number of events. That is, the first row would produce one event of type A, one event of type B, and two events of type C.

I would like to loop through each row and produce a set of uniform random numbers. For A, it would between 1 and 100, for B it would be between 101 and 200, and for C it would be between 201 and 300.

The output of the first row would have four numbers, one number between 1 and 100, one number between 101 and 200, and two numbers between 201 and 300. So a sample output of the first row might be:

[34, 105, 287, 221]

The second output row would have five numbers in it, the third row would have seven, etc. I would like to store it in my array of NaNs by overwriting the NaNs that get replaced in each row. Can anyone please help with this? Thanks!

CodePudding user response:

I've got a rather inefficient/unvectorised method which may or may not be what you're looking for, because one part of your question is unclear to me. Do you want the final array to have rows of different sizes, or to be the same size but padded with nans?

This solution assumes padding with nans, since you talked about the nans being overwritten and didn't mention the extra/unused nans being deleted. I'm also assuming that your ABC thing is structured into a numpy array of size (5,3), and I'm calling the array of nans results_arr.

import numpy as np
from random import randint

# Initializing the arrays
results_arr = np.full((5,10), np.nan)
abc = np.array([[1, 1, 2], [1, 2, 2], [2, 1, 4], [1, 2, 3], [0, 1, 2]])

# Loops through each row in ABC
for row_idx in range(len(abc)):
    a, b, c = abc[row_idx]

    # Here, I'm getting a number in the specified uniform distribution as many times as is specified in the A column. The other 2 loops do the same for the B and C columns.
    for i in range(0, a):
        results_arr[row_idx, i] = randint(1, 100)

    for j in range(a, a b):
        results_arr[row_idx, j] = randint(101, 200)

    for k in range(a b, a b c):
        results_arr[row_idx, k] = randint(201, 300)

Hope that helps!

P.S. Here's a solution with uneven rows. The result is stored in a list of lists because numpy doesn't support ragged arrays (i.e. rows of different lengths).

import numpy as np
from random import randint

# Initializations
results_arr = []
abc = np.array([[1, 1, 2], [1, 2, 2], [2, 1, 4], [1, 2, 3], [0, 1, 2]])

# Same code logic as before, just storing the results differently
for row_idx in range(len(abc)):
    a, b, c = abc[row_idx]
    results_this_row = []
    
    for i in range(0, a):
        results_this_row.append(randint(1, 100))
    for j in range(a, a b):
        results_this_row.append(randint(101, 200))
    for k in range(a b, a b c):
        results_this_row.append(randint(201, 300))
    
    results_arr.append(results_this_row)

I hope these two solutions cover what you're looking for!

  • Related