Python - 随机填充设置数为1的2D数组

时间:2015-11-19 18:06:09

标签: python arrays random

假设我有一个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

虽然这个有效,但它似乎是一种迂回方法。这样做有更好(即更有效)的方法吗?我预计会多次运行此代码(数十万甚至数百万),因此速度是一个问题。

2 个答案:

答案 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)