Home > Net >  Creating a random array from another array
Creating a random array from another array

Time:07-02

I am trying to figure out a way to "shuffle" an array without using inbuilt shuffle functions of random or numpy.

I have the following code, but it will select a cell more than once, and I would like to use only the values in Deck1. However, if Deck1 has two instances of 3 (for instance) then it should result in two instances of 3 in Deck2

I suspect this should be searching Deck2 as it is built for the value in Deck1, but I am not completely sure how to go about it, especially if Deck1 has multiple instances of a value.

def shuffler():
    n = int(input(" Please enter the number of cards in the deck: "))
    s = input("Should the deck be shuffled? (Y/N): ").lower()
    
    # Create the decks
    # First deck is filled with either random or ordered numbers
    if s == "y":
        Deck1 = np.random.randint(low = 0, high = n, size = n)
        print("Original deck:")
        print(Deck1)
        Deck2 = np.empty(n, np.int)
    else:
        Deck1 = np.arange(n)
        print("Original deck:")
        print(Deck1)
        Deck2 = np.empty(n, np.int)

    for i in Deck1:
        j = np.random.randint(0, n)
        Deck2[i] = Deck1[j]
        
    print("Shuffled deck:")
    print(Deck2)

CodePudding user response:

A few comments:

Deck1 = np.random.randint(low = 0, high = n, size = n) isn't a very good way of initializing a deck since it's supposed to contain n unique cards. You should use Deck1 = np.arange(n).

A way of shuffling a deck is to create a random array of positions, then swap the items in these positions. For example:

np.random.seed(42)
np.random.randint(low = 0, high = 10, size = 10)

yields array([6, 3, 7, 4, 6, 9, 2, 6, 7, 4]). Consider this a way of moving the card at position 0 to position 6. The card at position 6 could either be shifted to the right, or move to position 0. Similarly, the card at position 1 goes to 3, and the card at 3 goes to 1.

This is how I implemented your code:

import numpy as np
np.random.seed(42)  # Reproducible outputs
def shuffler(n = 10, s = "Y"): # Don't want to type 10 and 'Y' every time
    print("Original deck:")
    Deck = np.arange(n)
    print(Deck)

    if s.lower() == "y":
        positions = np.random.randint(low = 0, high = n, size = n)
        for i, position in enumerate(positions):
            Deck[i], Deck[position] = Deck[position], Deck[i] # Swaps
        print("Shuffled deck:")
        print(Deck)
shuffler()

Yielded

Original deck:
[0 1 2 3 4 5 6 7 8 9]
Shuffled deck:
[6 3 1 4 5 9 2 8 7 0]

CodePudding user response:

You can write your own shuffle function, but be careful to have a homogeneous distribution. Here is an implementation of the Durstenfeld shuffle algorithm:

def shuffle(arr):
    for i in range(len(arr) - 1, 0, -1):
        j = np.random.randint(0, i   1)
        arr[[i, j]] = arr[[j, i]] # Swap 

Then in your code:

Deck2 = np.copy(Deck1)
shuffle(Deck2)
  • Related