RE: graded randomness
Abdur-Rahman I am sure various modules available have ready-made solutions and I see others have replied to your question. The usual disclaimers apply. This is an academic discussion and not a statement of the right or only way to do an abstract task. So just a thought. You seem interested in a GENERAL situation where you have N situations with each having a specific probability and the probabilities sum to 1.0. If that is right, you are creating a partition where you can make a data structure listing N ordered items along with their individual probability. Given such a list, you can create another item that is a cumulative sum. In your example, your individual probabilities for ['green', 'red', 'blue'] are [0.4, 0.4, 0.2] but the use of lists is just for illustration. You might use a Numpy array as they have a cumulative sum function: import numpy as np np.cumsum([0.4, 0.4, 0.2]) Returns: array([0.4, 0.8, 1. ]) or viewed vertically: np.cumsum([0.4, 0.4, 0.2]).reshape(3,1) array([[0.4], [0.8], [1. ]]) Again, we are talking about a GENERAL solution but using this example to illustrate. To get a weighted probability now, you use the random module (or anything else) to generate a random number between 0 and 1. You search in the cumulative sum data structure to find the right range. A random value less than 0.4 should direct you to using green. If above that but less than 0.8, use red. Else, use blue. To do this properly, you can decide what data structures makes this easy to do. Maintaining three independent lists or arrays may not be optimal. The main idea is to find a way to segment your choices. So consider a different common example of rolling a pair of (six sided) standard dice. You know there are 6**2 possible outcomes. There is only one way to get a sum of 2 by rolling a one and another one. So the probability is 1/36 or .0277... and you can calculate the probabilities of all the other sums with a 7 being the most common roll at .1667. In this example your choices are rolls of 2 through 12 or 11 choices. The same logic applies. Generate 11 data measures and a cumulative sum. Just as illustration, I show code using a Pandas DataFrame object. import numpy as np import pandas as pd diceSumText = np.array(["two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve"]) diceSumVal = np.array(range(2,13)) diceProbability = np.array([1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]) / 36 diceProbCumSum = np.cumsum(diceProbability) Now combine those: mydata = pd.DataFrame({"Text": diceSumText, "Value": diceSumVal, "Prob": diceProbability, "Cum": diceProbCumSum}) print(mydata) Text Value Prob Cum 0 two 2 0.027778 0.027778 1three 3 0.06 0.08 2 four 4 0.08 0.17 3 five 5 0.11 0.28 4 six 6 0.138889 0.416667 5seven 7 0.17 0.58 6eight 8 0.138889 0.72 7 nine 9 0.11 0.83 8 ten 10 0.08 0.916667 9 eleven 11 0.06 0.97 10 twelve 12 0.027778 1.00 Again, you can do something any number of ways. This is just one. And in this format the indentation is not great. But it lets you write an algorithm that finds the highest 'index" that still is below the random number chosen and then select either the text or value that fits in that partition. Not to repeat, there are many other ways so feel free to innovate. -Original Message- From: Python-list On Behalf Of Abdur-Rahmaan Janhangeer Sent: Friday, December 28, 2018 2:45 PM To: Python Subject: Re: graded randomness well i wanted that to improve the following code: https://www.pythonmembers.club/2018/12/28/reviving-bertrand-russell-through- python/ that one i used the random list technique Abdur-Rahmaan Janhangeer http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius > -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: graded randomness
well i wanted that to improve the following code: https://www.pythonmembers.club/2018/12/28/reviving-bertrand-russell-through-python/ that one i used the random list technique Abdur-Rahmaan Janhangeer http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius > -- https://mail.python.org/mailman/listinfo/python-list
Re: graded randomness
woops @ben me too i got that solution but i'm searching for a neater answer. let us say i'm using it over new data, 1 million data of red blue green can be saved by just dealing with the probabilities ^^_ Abdur-Rahmaan Janhangeer http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius -- https://mail.python.org/mailman/listinfo/python-list
Re: graded randomness
On 2018-12-28 17:31, Abdur-Rahmaan Janhangeer wrote: > do you have something like > > choice(balls) > > >>> red Don't specify the "k=" (which defaults to 1 if you omit it) and use the first element of the results: >>> from random import choices >>> distribution = {"green":2, "red": 2, "blue": 1} >>> data, weights = zip(*distribution.items()) >>> choices(data, weights)[0] 'red' > and subsequent repetitions for long enough yield approximately 2/5 > times r 2/5 times g and 1/5 b You can sample it yourself: >>> from collections import defaultdict >>> a = defaultdict(int) >>> for i in range(1): ... a[choices(data, weights=weights)[0]] += 1 ... >>> dict(a) {'green': 3979, 'red': 4008, 'blue': 2013} though if you plan to, then it might be better/faster to use cum_weights instead, calculating it once and then reusing it rather than having choices() re-calculate the cumulative-weights on every call. > like one without random choice over list/tuples Not sure what you mean by this. -tkc -- https://mail.python.org/mailman/listinfo/python-list
Re: graded randomness
On 2018-12-28 16:15, Abdur-Rahmaan Janhangeer wrote: > greetings, > > let us say that i have a box of 5 balls, > > green balls - 2 with probability 2/5 > red balls 2 - with probability 2/5 > blue balls 1 - with probability 1/5 > > how to program the selection so that the random choices reflect the > probabilities? You're looking for what are called "weighted choices" which the random.choice() function provides as of Py3.6 https://docs.python.org/3/library/random.html#random.choices >>> from random import choices >>> distribution = {"green":2, "red": 2, "blue", 1} >>> data, weights = zip(*distribution.items()) >>> sum(weights) 5 >>> sorted(choices(data, weights=weights, k=20)) ['blue', 'blue', 'blue', 'blue', 'green', 'green', 'green', 'green', 'green', 'green', 'green', 'green', 'red', 'red', 'red', 'red', 'red', 'red', 'red', 'red'] -tim -- https://mail.python.org/mailman/listinfo/python-list
Re: graded randomness
ah yes, powerful enough for further customisations * scratches head thanks everybody ! Abdur-Rahmaan Janhangeer http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius -- https://mail.python.org/mailman/listinfo/python-list
Re: graded randomness
On Sat, Dec 29, 2018 at 12:28 AM Abdur-Rahmaan Janhangeer wrote: > > woops @ben me too i got that solution but i'm searching for a neater answer. > > let us say i'm using it over new data, 1 million data of red blue green can > be saved by just dealing with the probabilities ^^_ Assuming you're on Python 3.6 or newer, you should be able to use random.choices() for this. https://docs.python.org/3/library/random.html#random.choices >>> random.choices("spam", [10, 1, 3, 2]) ['a'] You can get any of the four letters back, but you're more likely to get 's' than anything else. Is that the sort of thing you're after? ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: graded randomness
@Tim do you have something like choice(balls) >>> red and subsequent repetitions for long enough yield approximately 2/5 times r 2/5 times g and 1/5 b like one without random choice over list/tuples Abdur-Rahmaan Janhangeer http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius -- https://mail.python.org/mailman/listinfo/python-list
Re: graded randomness
Abdur-Rahmaan Janhangeer writes: > let us say that i have a box of 5 balls, > > green balls - 2 with probability 2/5 > red balls 2 - with probability 2/5 > blue balls 1 - with probability 1/5 > > how to program the selection so that the random choices reflect the > probabilities? >>> import random >>> random.choice(["green", "green", "red", "red", "blue"]) Not a method that scales particularly well, but there's almost no context to evaluate solutions. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list