3

I'm trying to pick numbers from an array at random.

I can easily do this by picking an element using np.random.randint(len(myArray)) - but that gives a uniform distribution.

For my needs I need to pick a random number with higher probability of picking a number near the beginning of the array - so I think something like an exponential probability function would suit better.

Is there a way for me to generate a random integer in a range (1, 1000) using an exponential (or other, non-uniform distribution) to use as an array index?

  • See https://stackoverflow.com/questions/40244602/exponentially-distributed-random-generator-log-function-in-python for starters. – Selcuk Mar 15 '19 at 00:22

1 Answers1

3

You can assign an exponential probability vector to choice module from NumPy. The probability vector should add up to 1 therefore you normalize it by the sum of all probabilities.

import numpy as np
from numpy.random import choice

arr = np.arange(0, 1001)
prob = np.exp(arr/1000) # To avoid a large number
rand_draw = choice(arr, 1, p=prob/sum(prob))

To make sure the random distribution follows exponential behavior, you can plot it for 100000 random draws between 0 and 1000.

import matplotlib.pyplot as plt

# above code here

rand_draw = choice(arr, 100000, p=prob/sum(prob))

plt.hist(rand_draw, bins=100)
plt.show()

enter image description here

Sheldore
  • 37,862
  • 7
  • 57
  • 71
  • However, if the number of choices is small then numpy.random.choice is significantly slower than a basic implementation of the function. See: https://stackoverflow.com/q/18622781/6087087 – Fırat Kıyak Mar 02 '22 at 22:59