假设我有一个0的二维数组(8x8)。我想用预定数量的1来填充这个数组,但是以随机的方式。例如,假设我想在网格中随机放置 16个1 ,结果如下:
[[0, 0, 0, 1, 0, 0, 1, 0],
[1, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 1, 1, 0, 0],
[0, 1, 0, 0, 0, 1, 0, 0],
[0, 1, 1, 0, 0, 0, 0, 1]]
只要它是随机的(或者像Python允许的那样随机),1< s>的最终位置无关紧要。
我的代码在技术上有效,但我认为它的效率极低。我所做的就是将每个数字的概率设置为1到n/s
,其中n
是所需1的数量,而s
的大小是length = 8
numOnes = 16
while True:
board = [[(random.random() < float(numOnes)/(length**2))*1 for x in xrange(length)] for x in xrange(length)]
if sum([subarr.count(1) for subarr in board]) == 16:
break
print board
网格(即元素数量),然后我检查是否添加了正确数量的1。这是代码(Python 2.7):
On Error Resume Next
虽然这个有效,但它似乎是一种迂回方法。这样做有更好(即更有效)的方法吗?我预计会多次运行此代码(数十万甚至数百万),因此速度是一个问题。
答案 0 :(得分:8)
将16个1和48个0的列表混洗:
board = [1]*16 + 48*[0]
random.shuffle(board)
board = [board[i:i+8] for i in xrange(0, 64, 8)]
或用0填充棋盘并挑选16个位置的随机样本以将1s放入:
board = [[0]*8 for i in xrange(8)]
for pos in random.sample(xrange(64), 16):
board[pos//8][pos%8] = 1
答案 1 :(得分:2)
我做了那些,做了零,连接它们,洗牌,然后重新塑造。
import numpy as np
def make_board(shape, ones):
o = np.ones(ones, dtype=np.int)
z = np.zeros(np.product(shape) - ones, dtype=np.int)
board = np.concatenate([o, z])
np.random.shuffle(board)
return board.reshape(shape)
make_board((8,8), 16)
对于它的价值,user2357112使用numpy
的方法很快......
def make_board(shape, ones):
size = np.product(shape)
board = np.zeros(size, dtype=np.int)
i = np.random.choice(np.arange(size), ones)
board[i] = 1
return board.reshape(shape)