I need to generate a large number of random poker card decks. Speed is important so everything has to be in numpy matrix form.
I understand I can generate two cards from a deck as follows:
np.random.choice(12*4,2, replace=False)
How can I execute the same query so that a 2d array is created without a for loop? The difficulty is that each round will need to distribute from the original stack, so replace is only true for rows but False for columns.
I've also tried it with
originalDeck=np.arange(1,12*4)
np.random.shuffle(originalDeck)
But here as well we would need to generate a 2d array of the originalDeck and then each line? Is this possible?
Since you are only looking for pair of cards, you have only
1128
possible pairs (without replacement), so you could generate all pairs and then pick random cards from this set:Where
N_PAIRS
is the number of pairs you want.Benchmarks:
This method is really fast when
M
is very small, asM
gets bigger, the number of combinations increases exponentially, and thus even creating theall_pairs
array is not possible (already withM = 5
you have ~1700000 possible combinations).A another simple approach, slightly slower than @Holt best solution.
You can simulate
np.random.choice(..., replace=False)
's behavior with a trick here based onargsort/argpartition
. The idea is simple : We create a random array and sort it. The sorted indices thus obtained being unique would resemblenp.random.choice(..., replace=False)
.Since, we are looking to have a 2D array with such a feature, start with a random 2D array and for performance use
np.argpartition
for getting the first two sorted indices along each row to simulate2
cards picking.Thus, we would have a vectorized approach like so -
Runtime test -