0

I need to create a simulation of case assignment in Python:

For each item in a list it needs to be assigned value from one of the below location based on the %age of cases that need to be assigned to each country.

Country Case Load
US 30%
UK 30%
India 30%
Singapore 10%

For example, if there are 100 items in a python list, each needs to be assigned to either of the countries in the list. For example, once the count of cases assigned to UK reaches 30, it needs to stop assigning US anymore.

distro = {'US': 0.3, 'UK': 0.3, 'India': 0.3, 'Singapore': 0.1}

locations = []
for key in distro.keys():
    locations.append(key)
locations

loc_assign = []
cases = 100

distro = {'US': 0.3, 'UK': 0.3, 'India': 0.3, 'Singapore': 0.1}

locations = []
for key in distro.keys():
    locations.append(key)
locations

for i in range(cases):
    a = random.choice(locations)
    if loc_assign.count(a) < distro.get(a):
        loc_assign.append(a)
    else:
        a = random.choice(locations)
        loc_assign.append(a)

But the output I am getting is below not correct:

US: 0.27
UK: 0.3
India: 0.22
Singapore: 0.21

How to I get this to arrive at the target distribution percentage.

I am fairly new to Python and can't figure this out. Any help would be appreciated.

2
  • 3
    docs.python.org/dev/library/random.html#random.choices Commented Apr 25, 2021 at 17:55
  • For any solution to work, the number of cases must be divisible by the sum of case distributions. Otherwise, you will inevitably have an inexact case distribution. Also, use percentages instead of decimal point notation, because numbers stored via decimal point notation may be inexact. Commented Apr 25, 2021 at 17:59

2 Answers 2

1

Perhaps you can do it with random.sample():

from random import sample
from collections import Counter # Just to have a nice counter

population = ['US', 'UK', 'IN', 'SI']
weights = [3, 3, 3, 1]

c = Counter(sample(population, k=1, counts=weights)[0] for _ in range(1000))

print(c)

Which will give you something like this:

Counter({'UK': 308, 'IN': 302, 'US': 289, 'SI': 101}) 

As you can see, the distribution of values is very close to what you need in your post.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for your solution. However, blorgon's solution gives closer results.
No worries. Just tried to present you with an alternative. :-)
A little late but I am trying to run a simulation and this actually provides the right variation. This was not what I wanted but is exactly what I need. :)
I'm glad it helped.
I think something has changed in in the random.sample package. Getting an error: TypeError: sample() got an unexpected keyword argument 'counts'
|
0

Here is a solution that more closely replicates your original approach. The biggest problem was that you need to multiply the distribution by the cases in your if statement. Also using a while loop is better in this case:

import random

distro = {'US': 0.3, 'UK': 0.3, 'India': 0.3, 'Singapore': 0.1}

loc_assign = []
cases = 100

i = 0
while i < cases:
    a = random.choice(list(distro.keys()))
    if loc_assign.count(a) < distro.get(a)* cases:
        loc_assign.append(a)
        i += 1

print(loc_assign.count('US')) #30
print(loc_assign.count('UK')) #30
print(loc_assign.count('India')) #30
print(loc_assign.count('Singapore')) #10

Comments

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.