2

I have a list as such

a = [.5,.57,.67,.8,1,1.33,2,4]

Which looks like this when plotted: enter image description here

I need to randomly pick a number in this list. In Python, I would normally go like this:

c = random.choice(a)

Except... Doing this biases the pick towards a lower value (the density is higher around 1 than it is around 4).

How would I go about picking a list entry according to a uniform distribution. As in c = random.random()*3.5+.5, but actually picking from the list?

Lucien S.
  • 5,123
  • 10
  • 52
  • 88
  • Does the value being picked has to be element of the list? Otherwise depending on your data the eventual choice will still be biased... To some extent – Anzel Oct 19 '15 at 16:29
  • 2
    Let's see, it's either discrete or continuous. Maybe you could pick a random float in that interval, and then retrieve the element on the list closest to that value. – mescarra Oct 19 '15 at 16:30
  • Yes, it needs to be an element of the list – Lucien S. Oct 19 '15 at 16:30
  • Indeed, @mescarra, what's the best way to do so? recusivly? – Lucien S. Oct 19 '15 at 16:31
  • You could separete between sections (e.g 0-4), randomize a section and only then randomize inside the section. This way, it won't matter how many numbers there are in each section. You might just need to check for empty sections. – FirstOne Oct 19 '15 at 16:36
  • you can also do something like http://stackoverflow.com/questions/12141150/from-list-of-integers-get-number-closest-to-a-given-value then use `random.uniform` to get a random float number from 0.0-4.0 – R Nar Oct 19 '15 at 16:38
  • "Doing this biases the pick towards a lower value". Do yo mean you want the expected value of the pick to be `(a[0]+a[-1]])/2`? – toine Oct 19 '15 at 16:42

1 Answers1

1

You could get floats from an uniform distribution and then choosing the one on your list that's closest to this generated value. Like so:

a = [.5,.57,.67,.8,1,1.33,2,4]
p = map(lambda x: abs(random.uniform(0,4) - x), a)
c = a[p.index(min(p))]

Of course, you could do it more efficently given that your list is sorted.

mescarra
  • 695
  • 5
  • 16