If I understand your question correctly, you still want a uniform distribution for most numbers, but you want to specify that a single or a few specific values have a n% chance to be chosen?
You still can use np.random.choice
to accomplish this, but instead of using the values directly, you use those values to do something else.
Here is an example, lets say you wanted to have a uniform distribution, but n% chance that two specific values occur, lets say the distribution is [0.0,1.0) and the biased values 0.4435 and 0.89943, each with a 45% chance of occurring, and the otherwise normally distributed numbers have a 10% chance of occurring.
What you can do is make a choice of which "distribution" you use with a certain percentage using np.random.choice
, 10% uniform 45% 0.4435, and 45% 0.89943 here is some code as an example:
import numpy as np
from enum import Enum
class DistributionChoice(Enum):
Uniform = 0
SpecialNumberA = 1 # 0.4435
SpecialNumberB = 2 # 0.89943
def biased_uniform_distribution():
choices = [DistributionChoice.Uniform, DistributionChoice.SpecialNumberA, DistributionChoice.SpecialNumberB]
x = np.random.choice(choices, 1, p=[0.10, 0.45, 0.45])
#could use dictionary instead, but for simplicity sake, I'm using if statements.
if x == DistributionChoice.Uniform:
return np.random.uniform(0.0, 1.0)
elif x == DistributionChoice.SpecialNumberA:
return 0.4435
elif x == DistributionChoice.SpecialNumberB:
return 0.89943
def main(iterations):
for i in range(iterations):
print(biased_uniform_distribution())
if __name__ == "__main__":
main(100)
#results
0.4435
0.89943
0.5710925183758643
0.4435
0.4435
0.4435
0.4435
0.89943
0.89943
0.4435
0.89943
0.4435
0.5630141728887013
0.4435
0.89943
0.4435
0.89943
0.4435
0.4435
0.4435
0.89943
0.6302538459279832
0.89943
0.89943
0.4435
0.89943
0.89943
0.89943
0.4435
0.89943
0.89943
0.4435
0.09930005052912882
0.6756077455792501
0.89943
0.4435
0.15741601499964686
0.89943
0.89943
0.4435
0.89943
0.4435
0.4435
0.89943
0.89943
0.89943
0.89943
0.89943
0.89943
0.4435
0.4435
0.4435
0.89943
0.4435
0.89943
0.4435
0.89943
0.4435
0.89943
0.4435
0.89943
0.4435
0.4435
0.4435
0.89943
0.18955612016599943
0.89943
0.89943
0.89943
0.4435
0.4435
0.89943
0.7906889281625666
0.89943
0.89943
0.89943
0.89943
0.4435
0.89943
0.8019438261248141
0.4435
0.4435
0.89943
0.89943
0.4435
0.89943
0.4435
0.4435
0.89943
0.4435
0.89943
0.7575394533526174
0.89943
0.8283037670107836
0.5164249955320006
0.4435
0.5558117404002264
0.89943
0.89943
0.4435
Now one issue with this is that technically, there is a chance that these numbers could also show up in the same distribution. You can probably ignore this, in a actual real number system, there is a 1/infinity chance that any particular number shows up. In reality, double precision numbers do not have infinite resolution, so given enough time a number will show up again, but it is such a small probability that we can pretty much ignore it.
If you really wanted to remove this extremely minor issue, you would need to take more probabilities. One for each of the numbers you want to bias, and one for each exclusive range between your biased numbers (so that do not include that number).