0

In the REPL, I can do the following with numpy.random.choice():

>>> import numpy as np
>>> results = ["a", "b", "c"]
>>> probabilities = [0.5, 0.25, 0.25]

>>> choice = np.random.choice(results, 1, p=probabilities)
>>> choice
array(['a'],
      dtype='<U1')

>>> choice = np.random.choice(results, 1, p=probabilities)
>>> choice
array(['c'],
      dtype='<U1')

>>> choice = np.random.choice(results, 1, p=probabilities)
>>> choice
array(['b'],
      dtype='<U1')

As you can see, np.random.choice() returns something different every time it is called.

In my code, I have something like this:

# We start with a 2D array called areaMap
# It is already filled up to be a grid of None
# I want each square to change to a different biome instance based on its neighbours
# Our parameters are yMax and xMax, which are the maximum coordinates in each direction

yCounter = yMax
for yi in areaMap:
    xCounter = 0
    for xi in yi:
        biomeList = [woodsBiome(), desertBiome(), fieldBiome()]
        biomeProbabilities = np.array([0.1, 0.1, 0.1])

        # (perform some operations to change the probabilities)

        biomeProbabilities = biomeProbabilities / biomeProbabilities.sum()  # it should always sum to 1
        choice = np.random.choice(biomeList, 1, p=biomeProbabilities)[0]  # here we make a choice from biomeList based on biomeProbabilities
        areaMap[yCounter - 1][xCounter - 1] = choice  # set the correct area to choice
        xCounter += 1  # increment
    yCounter -= 1  # decrement (because of some other code, it can't increment)

This is part of a function to generate a 2D array containing different biomes. Later on in my code, after having run it, I get a result like this:

^~~__^_~_^~^^~^^^__~
^~~__^_~_^~^^~^^^__~
^~~__^_~_^~^^~^^^__~
^~~__^_~_^~^^~^^^__~
^~~__^_~_^~^^~^^^__~
^~~__^_~_^~^^~^^^__~
^~~__^_~_^~^^~^^^__~
^~~__^_~_^~^^~^^^__~
^~~__^_~_^~^^~^^^__~
^~~__^_~_^~^^~^^^__~

where each character (^, ~, _) represents a different biome.

The map comes up with the same results for each line of the 2D array.

Why is this happening and how can I fix it?

1 Answers1

2

The issue is in the line "We start with a 2D array called areaMap". First, it's not really a 2D array, it's a list of lists. You did not show how you initialized it, but from the result it's apparent this list has the issue that Eric pointed out: areaMap[0], areaMap[1], areaMap[2],... are all references to the same list. See How to clone or copy a list? for an explanation and how to avoid this.

Since you are using NumPy anyway, why not just use an actual 2D array areaMap? Like

areaMap = np.empty((M, N), dtype="U1")

where (M, N) is the shape of array, and data type declares that it will contain strings of length 1 (which seems to be the case in your example). The syntax for accessing array elements is simpler:

areaMap[yCounter - 1, xCounter - 1]

and no issues like you encountered will arise.

  • I'm actually storing instances of different classes (all inheriting from one), how would I do that? –  Oct 23 '17 at 15:15
  • 1
    Declaring an array of objects: `areaMap = np.empty((M, N), dtype=object)` –  Oct 23 '17 at 15:49