How to randomly throw numbers in a 2D dimensional board












2















I have a 50x50 2D dimensional board with empty cells now. I want to fill 20% cells with 0, 30% cells with 1, 30% cells with 2 and 20% cells with 3. How to randomly throw these 4 numbers onto the board with the percentages?



  import numpy as np
from numpy import random

dim = 50
map = [[" "for i in range(dim)] for j in range(dim)]
print(map)









share|improve this question


















  • 2





    Read up np.random.choice

    – Rocky Li
    Nov 13 '18 at 15:58











  • Do you want these exact percentages, in random positions, or do you want numbers drawn randomly at these proportions? (Big difference, since you will not get exactly the proportion in the second case.)

    – alexis
    Nov 13 '18 at 16:23













  • @alexis exact percentages in random positions

    – user10381476
    Nov 13 '18 at 16:25











  • Good, then a shuffle-type approach is the way to go. You've got answers for both interpretations already...

    – alexis
    Nov 13 '18 at 16:26


















2















I have a 50x50 2D dimensional board with empty cells now. I want to fill 20% cells with 0, 30% cells with 1, 30% cells with 2 and 20% cells with 3. How to randomly throw these 4 numbers onto the board with the percentages?



  import numpy as np
from numpy import random

dim = 50
map = [[" "for i in range(dim)] for j in range(dim)]
print(map)









share|improve this question


















  • 2





    Read up np.random.choice

    – Rocky Li
    Nov 13 '18 at 15:58











  • Do you want these exact percentages, in random positions, or do you want numbers drawn randomly at these proportions? (Big difference, since you will not get exactly the proportion in the second case.)

    – alexis
    Nov 13 '18 at 16:23













  • @alexis exact percentages in random positions

    – user10381476
    Nov 13 '18 at 16:25











  • Good, then a shuffle-type approach is the way to go. You've got answers for both interpretations already...

    – alexis
    Nov 13 '18 at 16:26
















2












2








2








I have a 50x50 2D dimensional board with empty cells now. I want to fill 20% cells with 0, 30% cells with 1, 30% cells with 2 and 20% cells with 3. How to randomly throw these 4 numbers onto the board with the percentages?



  import numpy as np
from numpy import random

dim = 50
map = [[" "for i in range(dim)] for j in range(dim)]
print(map)









share|improve this question














I have a 50x50 2D dimensional board with empty cells now. I want to fill 20% cells with 0, 30% cells with 1, 30% cells with 2 and 20% cells with 3. How to randomly throw these 4 numbers onto the board with the percentages?



  import numpy as np
from numpy import random

dim = 50
map = [[" "for i in range(dim)] for j in range(dim)]
print(map)






python numpy






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 13 '18 at 15:56









user10381476user10381476

16




16








  • 2





    Read up np.random.choice

    – Rocky Li
    Nov 13 '18 at 15:58











  • Do you want these exact percentages, in random positions, or do you want numbers drawn randomly at these proportions? (Big difference, since you will not get exactly the proportion in the second case.)

    – alexis
    Nov 13 '18 at 16:23













  • @alexis exact percentages in random positions

    – user10381476
    Nov 13 '18 at 16:25











  • Good, then a shuffle-type approach is the way to go. You've got answers for both interpretations already...

    – alexis
    Nov 13 '18 at 16:26
















  • 2





    Read up np.random.choice

    – Rocky Li
    Nov 13 '18 at 15:58











  • Do you want these exact percentages, in random positions, or do you want numbers drawn randomly at these proportions? (Big difference, since you will not get exactly the proportion in the second case.)

    – alexis
    Nov 13 '18 at 16:23













  • @alexis exact percentages in random positions

    – user10381476
    Nov 13 '18 at 16:25











  • Good, then a shuffle-type approach is the way to go. You've got answers for both interpretations already...

    – alexis
    Nov 13 '18 at 16:26










2




2





Read up np.random.choice

– Rocky Li
Nov 13 '18 at 15:58





Read up np.random.choice

– Rocky Li
Nov 13 '18 at 15:58













Do you want these exact percentages, in random positions, or do you want numbers drawn randomly at these proportions? (Big difference, since you will not get exactly the proportion in the second case.)

– alexis
Nov 13 '18 at 16:23







Do you want these exact percentages, in random positions, or do you want numbers drawn randomly at these proportions? (Big difference, since you will not get exactly the proportion in the second case.)

– alexis
Nov 13 '18 at 16:23















@alexis exact percentages in random positions

– user10381476
Nov 13 '18 at 16:25





@alexis exact percentages in random positions

– user10381476
Nov 13 '18 at 16:25













Good, then a shuffle-type approach is the way to go. You've got answers for both interpretations already...

– alexis
Nov 13 '18 at 16:26







Good, then a shuffle-type approach is the way to go. You've got answers for both interpretations already...

– alexis
Nov 13 '18 at 16:26














4 Answers
4






active

oldest

votes


















2














One way to get this kind of randomness would be to start with a random permutation of the numbers from 0 to the total number of cells you have minus one.



perm = np.random.permutation(2500)


now you split the permutation according the proportions you want to get and treat the entries of the permutation as the indices of the array.



array = np.empty(2500)
p1 = int(0.2*2500)
p2 = int(0.3*2500)
p3 = int(0.3*2500)
array[perm[range(0, p1)]] = 0
array[perm[range(p1, p1 + p2)]] = 1
array[perm[range(p1 + p2, p3)]] = 2
array[perm[range(p1 + p2 + p3, 2500)]] = 3
array = array.reshape(50, 50)


This way you ensure the proportions for each number.






share|improve this answer
























  • Nice! Clear and to the point, and it uses numpy's mass assignment to do everything without loops.

    – alexis
    Nov 14 '18 at 11:04



















2














Since the percentages sum up to 1, you can start with a board of zeros



bsize = 50
board = np.zeros((bsize, bsize))


In this approach the board positions are interpreted as 1D postions, then we need a set of position equivalent to 80% of all positions.



for i, pos in enumerate(np.random.choice(bsize**2, int(0.8*bsize**2), replace=False)):
# the fisrt 30% will be set with 1
if i < int(0.3*bsize**2):
board[pos//bsize][pos%bsize] = 1
# the second 30% (between 30% and 60%) will be set with 2
elif i < int(0.6*bsize**2):
board[pos//bsize][pos%bsize] = 2
# the rest 20% (between 60% and 80%) will be set with 3
else:
board[pos//bsize][pos%bsize] = 3


At the end the last 20% of positions will remain as zeros





As suggested by @alexis in commentaries, this approach could became more simple by using shuffle method from random module:



from random import shuffle



bsize = 50
board = np.zeros((bsize, bsize))

l = list(range(bsize**2))
shuffle(l)

for i, pos in enumerate(l):
# the fisrt 30% will be set with 1
if i < int(0.3*bsize**2):
board[pos//bsize][pos%bsize] = 1
# the second 30% (between 30% and 60%) will be set with 2
elif i < int(0.6*bsize**2):
board[pos//bsize][pos%bsize] = 2
# the rest 20% (between 60% and 80%) will be set with 3
elif i < int(0.8*bsize**2):
board[pos//bsize][pos%bsize] = 3


The last 20% of positions will remain as zeros again.






share|improve this answer


























  • May want to consider using NumPy's own ndenumerate() for this approach

    – Brad Solomon
    Nov 13 '18 at 17:23











  • @BradSolomon I've clicked in the link and I do not noted any difference in comparison to python's built-in enumerate. Is there any advantage using ndenumerate instead of enumerate ?

    – Hemerson Tacon
    Nov 14 '18 at 0:17








  • 1





    ndenumerate() will iterate across all dimensions of an np array. enumerate only enumerates along the top dimension. Since you are using it on a 1-dimensional number range, there is no reason to prefer one to the other.

    – alexis
    Nov 14 '18 at 10:56






  • 1





    You are using np.random.choice() to select out the 20% that should be set to zero, then you use proportions for the other three values. Why make it so complicated? Just randomize (shuffle) the entire range(50*50), and apply your proportions.

    – alexis
    Nov 14 '18 at 11:01













  • @alexis Shuffle passed by my mind but I was thinking a way to apply it directly to the board, but nothing came to my mind. I will add this approach to the answer, it really seems to be more simple.

    – Hemerson Tacon
    Nov 14 '18 at 12:40



















0














A different approach (admittedly it's probabilistic so you won't get perfect proportions as the solution proposed by Brad Solomon)



import numpy as np
res = np.random.random((50, 50))

zeros = np.where(res <= 0.2, 0, 0)
ones = np.where(np.logical_and(res <= 0.5, res > 0.2), 1, 0)
twos = np.where(np.logical_and(res <= 0.8, res > 0.5), 2, 0)
threes = np.where(res > 0.8, 3, 0)

final_result = zeros + ones + twos + threes


Running



np.unique(final_result, return_counts=True)


yielded



(array([0, 1, 2, 3]), array([499, 756, 754, 491]))





share|improve this answer































    0














    Here's an approach with np.random.choice to shuffle indices, then filling those indices with repeats of the inserted ints. It will fill the array in the exact proportions that you specify:



    import numpy as np
    np.random.seed(444)

    board = np.zeros(50 * 50, dtype=np.uint8).flatten()

    # The "20% cells with 0" can be ignored since that is the default.
    #
    # This will work as long as the proportions are "clean" ints
    # (I.e. mod to 0; 2500 * 0.2 is a clean 500. Otherwise, need to do some rounding.)

    rpt = (board.shape[0] * np.array([0.3, 0.3, 0.2])).astype(int)
    repl = np.repeat([1, 2, 3], rpt)

    idx = np.random.choice(board.shape[0], size=repl.size, replace=False)

    board[idx] = repl
    board = board.reshape((50, 50))


    Resulting frequencies:



    >>> np.unique(board, return_counts=True)
    (array([0, 1, 2, 3], dtype=uint8), array([500, 750, 750, 500]))
    >>> board
    array([[1, 3, 2, ..., 3, 2, 2],
    [0, 0, 2, ..., 0, 2, 0],
    [1, 1, 1, ..., 2, 1, 0],
    ...,
    [1, 1, 2, ..., 2, 2, 2],
    [1, 2, 2, ..., 2, 1, 2],
    [2, 2, 2, ..., 1, 0, 1]], dtype=uint8)




    Approach



    Flatten the board. Easier to work with indices when the board is (temporarily) one-dimensional.



    rpt is a 1d vector of the number of repeats per int. It gets "zipped" together with [1, 2, 3] to create repl, which is length 2000. (80% of the size of the board; you don't need to worry about the 0s in this example.)



    The indices of the flattened array are effectively shuffled (idx), and the length of this shuffled array is constrained to the size of the replacement candidates. Lastly, those indices in the 1d board are filled with the replacements, after which it can be made 2d again.






    share|improve this answer

























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53284814%2fhow-to-randomly-throw-numbers-in-a-2d-dimensional-board%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      2














      One way to get this kind of randomness would be to start with a random permutation of the numbers from 0 to the total number of cells you have minus one.



      perm = np.random.permutation(2500)


      now you split the permutation according the proportions you want to get and treat the entries of the permutation as the indices of the array.



      array = np.empty(2500)
      p1 = int(0.2*2500)
      p2 = int(0.3*2500)
      p3 = int(0.3*2500)
      array[perm[range(0, p1)]] = 0
      array[perm[range(p1, p1 + p2)]] = 1
      array[perm[range(p1 + p2, p3)]] = 2
      array[perm[range(p1 + p2 + p3, 2500)]] = 3
      array = array.reshape(50, 50)


      This way you ensure the proportions for each number.






      share|improve this answer
























      • Nice! Clear and to the point, and it uses numpy's mass assignment to do everything without loops.

        – alexis
        Nov 14 '18 at 11:04
















      2














      One way to get this kind of randomness would be to start with a random permutation of the numbers from 0 to the total number of cells you have minus one.



      perm = np.random.permutation(2500)


      now you split the permutation according the proportions you want to get and treat the entries of the permutation as the indices of the array.



      array = np.empty(2500)
      p1 = int(0.2*2500)
      p2 = int(0.3*2500)
      p3 = int(0.3*2500)
      array[perm[range(0, p1)]] = 0
      array[perm[range(p1, p1 + p2)]] = 1
      array[perm[range(p1 + p2, p3)]] = 2
      array[perm[range(p1 + p2 + p3, 2500)]] = 3
      array = array.reshape(50, 50)


      This way you ensure the proportions for each number.






      share|improve this answer
























      • Nice! Clear and to the point, and it uses numpy's mass assignment to do everything without loops.

        – alexis
        Nov 14 '18 at 11:04














      2












      2








      2







      One way to get this kind of randomness would be to start with a random permutation of the numbers from 0 to the total number of cells you have minus one.



      perm = np.random.permutation(2500)


      now you split the permutation according the proportions you want to get and treat the entries of the permutation as the indices of the array.



      array = np.empty(2500)
      p1 = int(0.2*2500)
      p2 = int(0.3*2500)
      p3 = int(0.3*2500)
      array[perm[range(0, p1)]] = 0
      array[perm[range(p1, p1 + p2)]] = 1
      array[perm[range(p1 + p2, p3)]] = 2
      array[perm[range(p1 + p2 + p3, 2500)]] = 3
      array = array.reshape(50, 50)


      This way you ensure the proportions for each number.






      share|improve this answer













      One way to get this kind of randomness would be to start with a random permutation of the numbers from 0 to the total number of cells you have minus one.



      perm = np.random.permutation(2500)


      now you split the permutation according the proportions you want to get and treat the entries of the permutation as the indices of the array.



      array = np.empty(2500)
      p1 = int(0.2*2500)
      p2 = int(0.3*2500)
      p3 = int(0.3*2500)
      array[perm[range(0, p1)]] = 0
      array[perm[range(p1, p1 + p2)]] = 1
      array[perm[range(p1 + p2, p3)]] = 2
      array[perm[range(p1 + p2 + p3, 2500)]] = 3
      array = array.reshape(50, 50)


      This way you ensure the proportions for each number.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Nov 13 '18 at 16:27









      T. EwenT. Ewen

      512




      512













      • Nice! Clear and to the point, and it uses numpy's mass assignment to do everything without loops.

        – alexis
        Nov 14 '18 at 11:04



















      • Nice! Clear and to the point, and it uses numpy's mass assignment to do everything without loops.

        – alexis
        Nov 14 '18 at 11:04

















      Nice! Clear and to the point, and it uses numpy's mass assignment to do everything without loops.

      – alexis
      Nov 14 '18 at 11:04





      Nice! Clear and to the point, and it uses numpy's mass assignment to do everything without loops.

      – alexis
      Nov 14 '18 at 11:04













      2














      Since the percentages sum up to 1, you can start with a board of zeros



      bsize = 50
      board = np.zeros((bsize, bsize))


      In this approach the board positions are interpreted as 1D postions, then we need a set of position equivalent to 80% of all positions.



      for i, pos in enumerate(np.random.choice(bsize**2, int(0.8*bsize**2), replace=False)):
      # the fisrt 30% will be set with 1
      if i < int(0.3*bsize**2):
      board[pos//bsize][pos%bsize] = 1
      # the second 30% (between 30% and 60%) will be set with 2
      elif i < int(0.6*bsize**2):
      board[pos//bsize][pos%bsize] = 2
      # the rest 20% (between 60% and 80%) will be set with 3
      else:
      board[pos//bsize][pos%bsize] = 3


      At the end the last 20% of positions will remain as zeros





      As suggested by @alexis in commentaries, this approach could became more simple by using shuffle method from random module:



      from random import shuffle



      bsize = 50
      board = np.zeros((bsize, bsize))

      l = list(range(bsize**2))
      shuffle(l)

      for i, pos in enumerate(l):
      # the fisrt 30% will be set with 1
      if i < int(0.3*bsize**2):
      board[pos//bsize][pos%bsize] = 1
      # the second 30% (between 30% and 60%) will be set with 2
      elif i < int(0.6*bsize**2):
      board[pos//bsize][pos%bsize] = 2
      # the rest 20% (between 60% and 80%) will be set with 3
      elif i < int(0.8*bsize**2):
      board[pos//bsize][pos%bsize] = 3


      The last 20% of positions will remain as zeros again.






      share|improve this answer


























      • May want to consider using NumPy's own ndenumerate() for this approach

        – Brad Solomon
        Nov 13 '18 at 17:23











      • @BradSolomon I've clicked in the link and I do not noted any difference in comparison to python's built-in enumerate. Is there any advantage using ndenumerate instead of enumerate ?

        – Hemerson Tacon
        Nov 14 '18 at 0:17








      • 1





        ndenumerate() will iterate across all dimensions of an np array. enumerate only enumerates along the top dimension. Since you are using it on a 1-dimensional number range, there is no reason to prefer one to the other.

        – alexis
        Nov 14 '18 at 10:56






      • 1





        You are using np.random.choice() to select out the 20% that should be set to zero, then you use proportions for the other three values. Why make it so complicated? Just randomize (shuffle) the entire range(50*50), and apply your proportions.

        – alexis
        Nov 14 '18 at 11:01













      • @alexis Shuffle passed by my mind but I was thinking a way to apply it directly to the board, but nothing came to my mind. I will add this approach to the answer, it really seems to be more simple.

        – Hemerson Tacon
        Nov 14 '18 at 12:40
















      2














      Since the percentages sum up to 1, you can start with a board of zeros



      bsize = 50
      board = np.zeros((bsize, bsize))


      In this approach the board positions are interpreted as 1D postions, then we need a set of position equivalent to 80% of all positions.



      for i, pos in enumerate(np.random.choice(bsize**2, int(0.8*bsize**2), replace=False)):
      # the fisrt 30% will be set with 1
      if i < int(0.3*bsize**2):
      board[pos//bsize][pos%bsize] = 1
      # the second 30% (between 30% and 60%) will be set with 2
      elif i < int(0.6*bsize**2):
      board[pos//bsize][pos%bsize] = 2
      # the rest 20% (between 60% and 80%) will be set with 3
      else:
      board[pos//bsize][pos%bsize] = 3


      At the end the last 20% of positions will remain as zeros





      As suggested by @alexis in commentaries, this approach could became more simple by using shuffle method from random module:



      from random import shuffle



      bsize = 50
      board = np.zeros((bsize, bsize))

      l = list(range(bsize**2))
      shuffle(l)

      for i, pos in enumerate(l):
      # the fisrt 30% will be set with 1
      if i < int(0.3*bsize**2):
      board[pos//bsize][pos%bsize] = 1
      # the second 30% (between 30% and 60%) will be set with 2
      elif i < int(0.6*bsize**2):
      board[pos//bsize][pos%bsize] = 2
      # the rest 20% (between 60% and 80%) will be set with 3
      elif i < int(0.8*bsize**2):
      board[pos//bsize][pos%bsize] = 3


      The last 20% of positions will remain as zeros again.






      share|improve this answer


























      • May want to consider using NumPy's own ndenumerate() for this approach

        – Brad Solomon
        Nov 13 '18 at 17:23











      • @BradSolomon I've clicked in the link and I do not noted any difference in comparison to python's built-in enumerate. Is there any advantage using ndenumerate instead of enumerate ?

        – Hemerson Tacon
        Nov 14 '18 at 0:17








      • 1





        ndenumerate() will iterate across all dimensions of an np array. enumerate only enumerates along the top dimension. Since you are using it on a 1-dimensional number range, there is no reason to prefer one to the other.

        – alexis
        Nov 14 '18 at 10:56






      • 1





        You are using np.random.choice() to select out the 20% that should be set to zero, then you use proportions for the other three values. Why make it so complicated? Just randomize (shuffle) the entire range(50*50), and apply your proportions.

        – alexis
        Nov 14 '18 at 11:01













      • @alexis Shuffle passed by my mind but I was thinking a way to apply it directly to the board, but nothing came to my mind. I will add this approach to the answer, it really seems to be more simple.

        – Hemerson Tacon
        Nov 14 '18 at 12:40














      2












      2








      2







      Since the percentages sum up to 1, you can start with a board of zeros



      bsize = 50
      board = np.zeros((bsize, bsize))


      In this approach the board positions are interpreted as 1D postions, then we need a set of position equivalent to 80% of all positions.



      for i, pos in enumerate(np.random.choice(bsize**2, int(0.8*bsize**2), replace=False)):
      # the fisrt 30% will be set with 1
      if i < int(0.3*bsize**2):
      board[pos//bsize][pos%bsize] = 1
      # the second 30% (between 30% and 60%) will be set with 2
      elif i < int(0.6*bsize**2):
      board[pos//bsize][pos%bsize] = 2
      # the rest 20% (between 60% and 80%) will be set with 3
      else:
      board[pos//bsize][pos%bsize] = 3


      At the end the last 20% of positions will remain as zeros





      As suggested by @alexis in commentaries, this approach could became more simple by using shuffle method from random module:



      from random import shuffle



      bsize = 50
      board = np.zeros((bsize, bsize))

      l = list(range(bsize**2))
      shuffle(l)

      for i, pos in enumerate(l):
      # the fisrt 30% will be set with 1
      if i < int(0.3*bsize**2):
      board[pos//bsize][pos%bsize] = 1
      # the second 30% (between 30% and 60%) will be set with 2
      elif i < int(0.6*bsize**2):
      board[pos//bsize][pos%bsize] = 2
      # the rest 20% (between 60% and 80%) will be set with 3
      elif i < int(0.8*bsize**2):
      board[pos//bsize][pos%bsize] = 3


      The last 20% of positions will remain as zeros again.






      share|improve this answer















      Since the percentages sum up to 1, you can start with a board of zeros



      bsize = 50
      board = np.zeros((bsize, bsize))


      In this approach the board positions are interpreted as 1D postions, then we need a set of position equivalent to 80% of all positions.



      for i, pos in enumerate(np.random.choice(bsize**2, int(0.8*bsize**2), replace=False)):
      # the fisrt 30% will be set with 1
      if i < int(0.3*bsize**2):
      board[pos//bsize][pos%bsize] = 1
      # the second 30% (between 30% and 60%) will be set with 2
      elif i < int(0.6*bsize**2):
      board[pos//bsize][pos%bsize] = 2
      # the rest 20% (between 60% and 80%) will be set with 3
      else:
      board[pos//bsize][pos%bsize] = 3


      At the end the last 20% of positions will remain as zeros





      As suggested by @alexis in commentaries, this approach could became more simple by using shuffle method from random module:



      from random import shuffle



      bsize = 50
      board = np.zeros((bsize, bsize))

      l = list(range(bsize**2))
      shuffle(l)

      for i, pos in enumerate(l):
      # the fisrt 30% will be set with 1
      if i < int(0.3*bsize**2):
      board[pos//bsize][pos%bsize] = 1
      # the second 30% (between 30% and 60%) will be set with 2
      elif i < int(0.6*bsize**2):
      board[pos//bsize][pos%bsize] = 2
      # the rest 20% (between 60% and 80%) will be set with 3
      elif i < int(0.8*bsize**2):
      board[pos//bsize][pos%bsize] = 3


      The last 20% of positions will remain as zeros again.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 14 '18 at 13:06

























      answered Nov 13 '18 at 17:05









      Hemerson TaconHemerson Tacon

      9641315




      9641315













      • May want to consider using NumPy's own ndenumerate() for this approach

        – Brad Solomon
        Nov 13 '18 at 17:23











      • @BradSolomon I've clicked in the link and I do not noted any difference in comparison to python's built-in enumerate. Is there any advantage using ndenumerate instead of enumerate ?

        – Hemerson Tacon
        Nov 14 '18 at 0:17








      • 1





        ndenumerate() will iterate across all dimensions of an np array. enumerate only enumerates along the top dimension. Since you are using it on a 1-dimensional number range, there is no reason to prefer one to the other.

        – alexis
        Nov 14 '18 at 10:56






      • 1





        You are using np.random.choice() to select out the 20% that should be set to zero, then you use proportions for the other three values. Why make it so complicated? Just randomize (shuffle) the entire range(50*50), and apply your proportions.

        – alexis
        Nov 14 '18 at 11:01













      • @alexis Shuffle passed by my mind but I was thinking a way to apply it directly to the board, but nothing came to my mind. I will add this approach to the answer, it really seems to be more simple.

        – Hemerson Tacon
        Nov 14 '18 at 12:40



















      • May want to consider using NumPy's own ndenumerate() for this approach

        – Brad Solomon
        Nov 13 '18 at 17:23











      • @BradSolomon I've clicked in the link and I do not noted any difference in comparison to python's built-in enumerate. Is there any advantage using ndenumerate instead of enumerate ?

        – Hemerson Tacon
        Nov 14 '18 at 0:17








      • 1





        ndenumerate() will iterate across all dimensions of an np array. enumerate only enumerates along the top dimension. Since you are using it on a 1-dimensional number range, there is no reason to prefer one to the other.

        – alexis
        Nov 14 '18 at 10:56






      • 1





        You are using np.random.choice() to select out the 20% that should be set to zero, then you use proportions for the other three values. Why make it so complicated? Just randomize (shuffle) the entire range(50*50), and apply your proportions.

        – alexis
        Nov 14 '18 at 11:01













      • @alexis Shuffle passed by my mind but I was thinking a way to apply it directly to the board, but nothing came to my mind. I will add this approach to the answer, it really seems to be more simple.

        – Hemerson Tacon
        Nov 14 '18 at 12:40

















      May want to consider using NumPy's own ndenumerate() for this approach

      – Brad Solomon
      Nov 13 '18 at 17:23





      May want to consider using NumPy's own ndenumerate() for this approach

      – Brad Solomon
      Nov 13 '18 at 17:23













      @BradSolomon I've clicked in the link and I do not noted any difference in comparison to python's built-in enumerate. Is there any advantage using ndenumerate instead of enumerate ?

      – Hemerson Tacon
      Nov 14 '18 at 0:17







      @BradSolomon I've clicked in the link and I do not noted any difference in comparison to python's built-in enumerate. Is there any advantage using ndenumerate instead of enumerate ?

      – Hemerson Tacon
      Nov 14 '18 at 0:17






      1




      1





      ndenumerate() will iterate across all dimensions of an np array. enumerate only enumerates along the top dimension. Since you are using it on a 1-dimensional number range, there is no reason to prefer one to the other.

      – alexis
      Nov 14 '18 at 10:56





      ndenumerate() will iterate across all dimensions of an np array. enumerate only enumerates along the top dimension. Since you are using it on a 1-dimensional number range, there is no reason to prefer one to the other.

      – alexis
      Nov 14 '18 at 10:56




      1




      1





      You are using np.random.choice() to select out the 20% that should be set to zero, then you use proportions for the other three values. Why make it so complicated? Just randomize (shuffle) the entire range(50*50), and apply your proportions.

      – alexis
      Nov 14 '18 at 11:01







      You are using np.random.choice() to select out the 20% that should be set to zero, then you use proportions for the other three values. Why make it so complicated? Just randomize (shuffle) the entire range(50*50), and apply your proportions.

      – alexis
      Nov 14 '18 at 11:01















      @alexis Shuffle passed by my mind but I was thinking a way to apply it directly to the board, but nothing came to my mind. I will add this approach to the answer, it really seems to be more simple.

      – Hemerson Tacon
      Nov 14 '18 at 12:40





      @alexis Shuffle passed by my mind but I was thinking a way to apply it directly to the board, but nothing came to my mind. I will add this approach to the answer, it really seems to be more simple.

      – Hemerson Tacon
      Nov 14 '18 at 12:40











      0














      A different approach (admittedly it's probabilistic so you won't get perfect proportions as the solution proposed by Brad Solomon)



      import numpy as np
      res = np.random.random((50, 50))

      zeros = np.where(res <= 0.2, 0, 0)
      ones = np.where(np.logical_and(res <= 0.5, res > 0.2), 1, 0)
      twos = np.where(np.logical_and(res <= 0.8, res > 0.5), 2, 0)
      threes = np.where(res > 0.8, 3, 0)

      final_result = zeros + ones + twos + threes


      Running



      np.unique(final_result, return_counts=True)


      yielded



      (array([0, 1, 2, 3]), array([499, 756, 754, 491]))





      share|improve this answer




























        0














        A different approach (admittedly it's probabilistic so you won't get perfect proportions as the solution proposed by Brad Solomon)



        import numpy as np
        res = np.random.random((50, 50))

        zeros = np.where(res <= 0.2, 0, 0)
        ones = np.where(np.logical_and(res <= 0.5, res > 0.2), 1, 0)
        twos = np.where(np.logical_and(res <= 0.8, res > 0.5), 2, 0)
        threes = np.where(res > 0.8, 3, 0)

        final_result = zeros + ones + twos + threes


        Running



        np.unique(final_result, return_counts=True)


        yielded



        (array([0, 1, 2, 3]), array([499, 756, 754, 491]))





        share|improve this answer


























          0












          0








          0







          A different approach (admittedly it's probabilistic so you won't get perfect proportions as the solution proposed by Brad Solomon)



          import numpy as np
          res = np.random.random((50, 50))

          zeros = np.where(res <= 0.2, 0, 0)
          ones = np.where(np.logical_and(res <= 0.5, res > 0.2), 1, 0)
          twos = np.where(np.logical_and(res <= 0.8, res > 0.5), 2, 0)
          threes = np.where(res > 0.8, 3, 0)

          final_result = zeros + ones + twos + threes


          Running



          np.unique(final_result, return_counts=True)


          yielded



          (array([0, 1, 2, 3]), array([499, 756, 754, 491]))





          share|improve this answer













          A different approach (admittedly it's probabilistic so you won't get perfect proportions as the solution proposed by Brad Solomon)



          import numpy as np
          res = np.random.random((50, 50))

          zeros = np.where(res <= 0.2, 0, 0)
          ones = np.where(np.logical_and(res <= 0.5, res > 0.2), 1, 0)
          twos = np.where(np.logical_and(res <= 0.8, res > 0.5), 2, 0)
          threes = np.where(res > 0.8, 3, 0)

          final_result = zeros + ones + twos + threes


          Running



          np.unique(final_result, return_counts=True)


          yielded



          (array([0, 1, 2, 3]), array([499, 756, 754, 491]))






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 13 '18 at 16:23









          Ian QuahIan Quah

          636613




          636613























              0














              Here's an approach with np.random.choice to shuffle indices, then filling those indices with repeats of the inserted ints. It will fill the array in the exact proportions that you specify:



              import numpy as np
              np.random.seed(444)

              board = np.zeros(50 * 50, dtype=np.uint8).flatten()

              # The "20% cells with 0" can be ignored since that is the default.
              #
              # This will work as long as the proportions are "clean" ints
              # (I.e. mod to 0; 2500 * 0.2 is a clean 500. Otherwise, need to do some rounding.)

              rpt = (board.shape[0] * np.array([0.3, 0.3, 0.2])).astype(int)
              repl = np.repeat([1, 2, 3], rpt)

              idx = np.random.choice(board.shape[0], size=repl.size, replace=False)

              board[idx] = repl
              board = board.reshape((50, 50))


              Resulting frequencies:



              >>> np.unique(board, return_counts=True)
              (array([0, 1, 2, 3], dtype=uint8), array([500, 750, 750, 500]))
              >>> board
              array([[1, 3, 2, ..., 3, 2, 2],
              [0, 0, 2, ..., 0, 2, 0],
              [1, 1, 1, ..., 2, 1, 0],
              ...,
              [1, 1, 2, ..., 2, 2, 2],
              [1, 2, 2, ..., 2, 1, 2],
              [2, 2, 2, ..., 1, 0, 1]], dtype=uint8)




              Approach



              Flatten the board. Easier to work with indices when the board is (temporarily) one-dimensional.



              rpt is a 1d vector of the number of repeats per int. It gets "zipped" together with [1, 2, 3] to create repl, which is length 2000. (80% of the size of the board; you don't need to worry about the 0s in this example.)



              The indices of the flattened array are effectively shuffled (idx), and the length of this shuffled array is constrained to the size of the replacement candidates. Lastly, those indices in the 1d board are filled with the replacements, after which it can be made 2d again.






              share|improve this answer






























                0














                Here's an approach with np.random.choice to shuffle indices, then filling those indices with repeats of the inserted ints. It will fill the array in the exact proportions that you specify:



                import numpy as np
                np.random.seed(444)

                board = np.zeros(50 * 50, dtype=np.uint8).flatten()

                # The "20% cells with 0" can be ignored since that is the default.
                #
                # This will work as long as the proportions are "clean" ints
                # (I.e. mod to 0; 2500 * 0.2 is a clean 500. Otherwise, need to do some rounding.)

                rpt = (board.shape[0] * np.array([0.3, 0.3, 0.2])).astype(int)
                repl = np.repeat([1, 2, 3], rpt)

                idx = np.random.choice(board.shape[0], size=repl.size, replace=False)

                board[idx] = repl
                board = board.reshape((50, 50))


                Resulting frequencies:



                >>> np.unique(board, return_counts=True)
                (array([0, 1, 2, 3], dtype=uint8), array([500, 750, 750, 500]))
                >>> board
                array([[1, 3, 2, ..., 3, 2, 2],
                [0, 0, 2, ..., 0, 2, 0],
                [1, 1, 1, ..., 2, 1, 0],
                ...,
                [1, 1, 2, ..., 2, 2, 2],
                [1, 2, 2, ..., 2, 1, 2],
                [2, 2, 2, ..., 1, 0, 1]], dtype=uint8)




                Approach



                Flatten the board. Easier to work with indices when the board is (temporarily) one-dimensional.



                rpt is a 1d vector of the number of repeats per int. It gets "zipped" together with [1, 2, 3] to create repl, which is length 2000. (80% of the size of the board; you don't need to worry about the 0s in this example.)



                The indices of the flattened array are effectively shuffled (idx), and the length of this shuffled array is constrained to the size of the replacement candidates. Lastly, those indices in the 1d board are filled with the replacements, after which it can be made 2d again.






                share|improve this answer




























                  0












                  0








                  0







                  Here's an approach with np.random.choice to shuffle indices, then filling those indices with repeats of the inserted ints. It will fill the array in the exact proportions that you specify:



                  import numpy as np
                  np.random.seed(444)

                  board = np.zeros(50 * 50, dtype=np.uint8).flatten()

                  # The "20% cells with 0" can be ignored since that is the default.
                  #
                  # This will work as long as the proportions are "clean" ints
                  # (I.e. mod to 0; 2500 * 0.2 is a clean 500. Otherwise, need to do some rounding.)

                  rpt = (board.shape[0] * np.array([0.3, 0.3, 0.2])).astype(int)
                  repl = np.repeat([1, 2, 3], rpt)

                  idx = np.random.choice(board.shape[0], size=repl.size, replace=False)

                  board[idx] = repl
                  board = board.reshape((50, 50))


                  Resulting frequencies:



                  >>> np.unique(board, return_counts=True)
                  (array([0, 1, 2, 3], dtype=uint8), array([500, 750, 750, 500]))
                  >>> board
                  array([[1, 3, 2, ..., 3, 2, 2],
                  [0, 0, 2, ..., 0, 2, 0],
                  [1, 1, 1, ..., 2, 1, 0],
                  ...,
                  [1, 1, 2, ..., 2, 2, 2],
                  [1, 2, 2, ..., 2, 1, 2],
                  [2, 2, 2, ..., 1, 0, 1]], dtype=uint8)




                  Approach



                  Flatten the board. Easier to work with indices when the board is (temporarily) one-dimensional.



                  rpt is a 1d vector of the number of repeats per int. It gets "zipped" together with [1, 2, 3] to create repl, which is length 2000. (80% of the size of the board; you don't need to worry about the 0s in this example.)



                  The indices of the flattened array are effectively shuffled (idx), and the length of this shuffled array is constrained to the size of the replacement candidates. Lastly, those indices in the 1d board are filled with the replacements, after which it can be made 2d again.






                  share|improve this answer















                  Here's an approach with np.random.choice to shuffle indices, then filling those indices with repeats of the inserted ints. It will fill the array in the exact proportions that you specify:



                  import numpy as np
                  np.random.seed(444)

                  board = np.zeros(50 * 50, dtype=np.uint8).flatten()

                  # The "20% cells with 0" can be ignored since that is the default.
                  #
                  # This will work as long as the proportions are "clean" ints
                  # (I.e. mod to 0; 2500 * 0.2 is a clean 500. Otherwise, need to do some rounding.)

                  rpt = (board.shape[0] * np.array([0.3, 0.3, 0.2])).astype(int)
                  repl = np.repeat([1, 2, 3], rpt)

                  idx = np.random.choice(board.shape[0], size=repl.size, replace=False)

                  board[idx] = repl
                  board = board.reshape((50, 50))


                  Resulting frequencies:



                  >>> np.unique(board, return_counts=True)
                  (array([0, 1, 2, 3], dtype=uint8), array([500, 750, 750, 500]))
                  >>> board
                  array([[1, 3, 2, ..., 3, 2, 2],
                  [0, 0, 2, ..., 0, 2, 0],
                  [1, 1, 1, ..., 2, 1, 0],
                  ...,
                  [1, 1, 2, ..., 2, 2, 2],
                  [1, 2, 2, ..., 2, 1, 2],
                  [2, 2, 2, ..., 1, 0, 1]], dtype=uint8)




                  Approach



                  Flatten the board. Easier to work with indices when the board is (temporarily) one-dimensional.



                  rpt is a 1d vector of the number of repeats per int. It gets "zipped" together with [1, 2, 3] to create repl, which is length 2000. (80% of the size of the board; you don't need to worry about the 0s in this example.)



                  The indices of the flattened array are effectively shuffled (idx), and the length of this shuffled array is constrained to the size of the replacement candidates. Lastly, those indices in the 1d board are filled with the replacements, after which it can be made 2d again.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 13 '18 at 16:26

























                  answered Nov 13 '18 at 16:14









                  Brad SolomonBrad Solomon

                  13.4k73482




                  13.4k73482






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53284814%2fhow-to-randomly-throw-numbers-in-a-2d-dimensional-board%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Bressuire

                      Vorschmack

                      Quarantine