Generate random integers with two constraints (sum and local maximum) in Python

Viewed 363

I have a dataframe where I want to create random numbers in a new column. The random numbers must fulfill two constraints:

  1. The random numbers must add up to a specified sum (in the example, the sum is 300)
  2. For each observation, the random numbers must not exceed a value in the constraint column.

In the example below, the constraints are fulfilled because the sum is 300 and the random number does not exceed the constraint column.

Example:

GEOID CONSTRAINT RANDOM
010010000001 100 80
010010000002 50 40
010010000003 75 60
010010000004 75 60
010010000005 100 60

It seems having random numbers totaling a sum has been demonstrated but I do not see an example with a second constraint.

Edit for clarity: The new column must be integers. The minimum lower bound value is 0.

1 Answers

You could use the multinomial distribution to build an approximate answer:

def sample(total, constraints):
    import numpy as np
    rng = np.random.default_rng()
    samples = rng.multinomial(total, constraints / constraints.sum(), size=100)
    return next(val for val in samples if np.all(val < constraints))


df["RANDOM"] = sample(300, df["CONSTRAINT"].values)
print(df)

Output

             GEOID  CONSTRAINT  RANDOM
0  10010000001         100      81
1  10010000002          50      42
2  10010000003          75      57
3  10010000004          75      53
4  10010000005         100      67

Thanks goes to @Michael Szczesny for testing the solution.

The key to solve this, relies in (quote from numpy docs):

Its values, X_i = [X_0, X_1, ..., X_p], represent the number of times the outcome was i.

see more details in this blog post.

Related