How to randomly throw numbers in a 2D dimensional board
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
add a comment |
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
2
Read upnp.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
add a comment |
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
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
python numpy
asked Nov 13 '18 at 15:56
user10381476user10381476
16
16
2
Read upnp.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
add a comment |
2
Read upnp.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
add a comment |
4 Answers
4
active
oldest
votes
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.
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
add a comment |
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.
May want to consider using NumPy's ownndenumerate()
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-inenumerate
. Is there any advantage usingndenumerate
instead ofenumerate
?
– Hemerson Tacon
Nov 14 '18 at 0:17
1
ndenumerate()
will iterate across all dimensions of annp
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 usingnp.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 entirerange(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
|
show 1 more comment
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]))
add a comment |
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.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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.
May want to consider using NumPy's ownndenumerate()
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-inenumerate
. Is there any advantage usingndenumerate
instead ofenumerate
?
– Hemerson Tacon
Nov 14 '18 at 0:17
1
ndenumerate()
will iterate across all dimensions of annp
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 usingnp.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 entirerange(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
|
show 1 more comment
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.
May want to consider using NumPy's ownndenumerate()
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-inenumerate
. Is there any advantage usingndenumerate
instead ofenumerate
?
– Hemerson Tacon
Nov 14 '18 at 0:17
1
ndenumerate()
will iterate across all dimensions of annp
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 usingnp.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 entirerange(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
|
show 1 more comment
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.
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.
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 ownndenumerate()
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-inenumerate
. Is there any advantage usingndenumerate
instead ofenumerate
?
– Hemerson Tacon
Nov 14 '18 at 0:17
1
ndenumerate()
will iterate across all dimensions of annp
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 usingnp.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 entirerange(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
|
show 1 more comment
May want to consider using NumPy's ownndenumerate()
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-inenumerate
. Is there any advantage usingndenumerate
instead ofenumerate
?
– Hemerson Tacon
Nov 14 '18 at 0:17
1
ndenumerate()
will iterate across all dimensions of annp
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 usingnp.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 entirerange(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
|
show 1 more comment
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]))
add a comment |
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]))
add a comment |
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]))
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]))
answered Nov 13 '18 at 16:23
Ian QuahIan Quah
636613
636613
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
edited Nov 13 '18 at 16:26
answered Nov 13 '18 at 16:14
Brad SolomonBrad Solomon
13.4k73482
13.4k73482
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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