2

I am currently using the numpy.random.uniform function to generate random decimals within a certain range.

x = np.random.uniform(-5, 5, (1, 2))

However, I want to add a probability for a certain random value to occur. I know the np.random.choicefunction has it, but I want to produce decimals, not whole numbers. Is there a way to generate random decimals and give them probabilities?

kdf
  • 358
  • 4
  • 16
  • So why can't you fill an array with N values generated by `np.random.uniform` and pass that array to `np.random.choice` along with a probability array? `np.random.choice` allows you to specify the possible values, and they do not need to be integers. See [docs](https://het.as.utexas.edu/HET/Software/Numpy/reference/generated/numpy.random.choice.html) – Paul Aug 02 '19 at 05:28
  • The most general way to create random distributions are `scipy.stats.rv_continuous` and `scipy.stats.rv_discrete`. May be overkill, though, depending on your exact needs. – Paul Panzer Aug 02 '19 at 06:01
  • Possible duplicate of [Generate random numbers with a given (numerical) distribution](https://stackoverflow.com/questions/4265988/generate-random-numbers-with-a-given-numerical-distribution) – Joe Aug 02 '19 at 08:08
  • https://stackoverflow.com/a/4266645/7919597 – Joe Aug 02 '19 at 08:08

1 Answers1

0

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).

Krupip
  • 4,404
  • 2
  • 32
  • 54
  • Hey @kdf that's great! Would you mind accepting my answer? I see you're relatively new to SO, so I'll explain some stuff just in case. Clicking the check mark next to the upvote button on my answer will give both me *and you* points, and marks the answer as "accepted" as in it solves your problem. – Krupip Aug 03 '19 at 02:35