Reputation: 1269
I have a list of lists, like so:
a = [[1,2],[2,3]]
I want to create a random list with replacement of a given size from a
. The numpy.random.choice()
method only accepts 1D arrays. I can write my own function to do this, but is there already an optimized way?
Expected output:
[[1,2],[1,2],[2,3],[2,3]]
// the size (4 here) has to be a parameter passed to the function
Upvotes: 7
Views: 9408
Reputation: 29740
As of Python 3.6, you can directly use random.choices
.
random.choices(list_of_lists, k=sample_size)
## [[1, 2], [3, 4], [3, 4], [1, 2]]
A rough benchmark suggests this seems to be more performant on varying sample sizes than the list comprehension approach.
>>> list_of_lists = [[1, 2], [3, 4]]
>>> sample_size = 4
>>> %timeit [random.choice(list_of_lists) for _ in range(sample_size)]
4.49 µs ± 20.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
>>> %timeit random.choices(list_of_lists, k=sample_size)
1.99 µs ± 14.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
>>> list_of_lists *= 100
>>> sample_size *= 1000
>>> %timeit [random.choice(list_of_lists) for _ in range(sample_size)]
3.54 ms ± 28.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
>>> %timeit random.choices(list_of_lists, k=sample_size)
927 µs ± 1.39 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Upvotes: 1
Reputation: 44615
The more_itertools
library implements more_itertools.random_combination_with_replacement
:
import more_itertools as mit
list_of_lists = [[1, 2], [2, 3]]
sample_size = 4
list(mit.random_combination_with_replacement(list_of_lists, sample_size))
# [[1, 2], [1, 2], [2, 3], [2, 3]]
Upvotes: 0
Reputation: 1548
You can simply call the standard library's random.choice()
repeatedly. No need for numpy
.
>>> list_of_lists = [[1, 2], [2, 3]]
>>> sample_size = 4
>>> [random.choice(list_of_lists) for _ in range(sample_size)]
[[1, 2], [2, 3], [1, 2], [1, 2]]
This is an alternative to random.sample()
that works without replacement and lets you choose a “sample” larger than the size of the original population.
Upvotes: 11
Reputation: 14498
Using numpy:
size = 4
a = np.array([[1,2],[2,3]])
b = np.random.randint(len(a), size = size)
a[b,:]
Out[93]:
array([[2, 3],
[2, 3],
[2, 3],
[1, 2]])
Upvotes: 1