Reputation: 57471
According to the http://docs.scipy.org/doc/numpy-dev/reference/generated/numpy.random.choice.html, using the replace = False
with Numpy's random.choice
method should make the sample without replacement. However, this does not seem to work for me:
In [33]: import numpy as np
In [34]: arr = range(5)
In [35]: number = np.random.choice(arr, replace = False)
In [36]: arr
Out[36]: [0, 1, 2, 3, 4]
The array arr
is still range(5)
after sampling, and not missing a (random) number as I would expect. How could I sample a number from range(5)
without replacement?
Upvotes: 4
Views: 14712
Reputation: 3967
As mentioned in one of the comments, np.choice selects with or without replacement, a series of numbers from a sequence. But it does not modify the sequence.
Easy alternative
arr = range(5)
# numbers below will never contain repeated numbers (replace=False)
numbers = np.random.choice(arr, 3, replace=False)
The behaviour I think you want would be:
arr = range(5)
all_but_one = np.random.choice(arr, len(arr) -1, replace=False)
so you would select N-1 numbers without replacement (to avoid repetitions), effectively removing a random element from the iterable.
More efficient alternative
arr = range(5)
random_index = np.random.randint(0, len(arr))
arr.pop(random_index)
Upvotes: 12
Reputation: 57471
I ended up defining a function using the random
library:
import random
def sample_without_replacement(arr):
random.shuffle(arr)
return arr.pop()
Its use is shown below:
In [51]: arr = range(5)
In [52]: number = sample_without_replacement(arr)
In [53]: number
Out[53]: 4
In [54]: arr
Out[54]: [2, 0, 1, 3]
Note that the method also shuffles the array in place, but for my purposes that doesn't matter.
Upvotes: 1