0

I use the weight in random.choice, so if I remove after selection, I'm afraid it would mess up the weight. pop_fit_sorted is an array of arrays using numpy and percentage is an aray with the weights.

parents_list = random.choices(pop_fit_sorted, weights=percentage, k=2)

That's the code i'm using. But it can sometimes select the same array twice. How to alway select 2 different arrays?

Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
João Vitor Degrandi
  • 3,417
  • 2
  • 8
  • 8
  • Try this https://gist.github.com/cvanweelden/4971289 or use [`numpy.choice`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.random.choice.html) which allows weights and to select without replacement (i.e. don't select the same thing twice). See also https://stackoverflow.com/questions/3679694/a-weighted-version-of-random-choice – Stuart Sep 09 '18 at 21:21
  • 1
    [`choices`](https://docs.python.org/3/library/random.html#random.choices) is "chosen from the population with replacement." [`sample`](https://docs.python.org/3/library/random.html#random.sample) is "for random sampling without replacement." If you want sampling without replacement (to not get the same array twice), just use `sample` instead of `choices`. If you want *weighted* sampling without replacement, you can't use either; you have to write a wrapper—or, better, just use numpy.random instead of the stdlib random. – abarnert Sep 09 '18 at 21:25

1 Answers1

1

Note about random.choices():

the relative weights are converted to cumulative weights before making selections.

So you could do something like:

items = {1:0.6, 2:0.3, 3:0.1}
el1 = random.choices(list(items.keys()), weights=list(items.values()), k=1)[0]
items[el1] = 0
el2 = random.choices(list(items.keys()), weights= list(items.values()), k=1)[0]

to be sure to get 2 distinct elements.

Or, as suggested, you may use numpy.random.choice():

np.random.choice(list(items.keys()), replace=False, size=2, p=list(items.values()))

but in this case you need to convert your weights to probabilities.

abc
  • 11,579
  • 2
  • 26
  • 51