您可以在 [q, p] 中为每一行生成一个随机数,然后在每一行中设置那么多随机数。如果高效是指矢量化,那么是的,有一种有效的方法。诀窍是模拟采样而不在一个轴上进行替换,但在另一个轴上进行替换。这可以通过np.argsort 完成。您可以通过将随机向量转换为掩码来选择可变数量的索引。
def randbin(m, n, p, q):
# output to assign ones into
result = np.zeros((m, n), dtype=bool)
# simulate sampling with replacement in one axis
col_ind = np.argsort(np.random.random(size=(m, n)), axis=1)
# figure out how many samples to take in each row
count = np.random.randint(p, q + 1, size=(m, 1))
# turn it into a mask over col_ind using a clever broadcast
mask = np.arange(n) < count
# apply the mask not only to col_ind, but also the corresponding row_ind
col_ind = col_ind[mask]
row_ind = np.broadcast_to(np.arange(m).reshape(-1, 1), (m, n))[mask]
# Set the corresponding elements to 1
result[row_ind, col_ind] = 1
return result
进行选择以使row_ind 中每个相等值的运行长度在p 和q 元素之间。 col_ind对应的元素是唯一的,并且在每一行内均匀分布。
另一种选择是@Prunes solution。它需要np.argsort 独立地打乱行,因为np.random.shuffle 会将行保持在一起:
def randbin(m, n, p, q):
# make the unique rows
options = np.arange(n) < np.arange(p, q + 1).reshape(-1, 1)
# select random unique row to go into each output row
selection = np.random.choice(options.shape[0], size=m, replace=True)
# perform the selection
result = options[selection]
# create indices to shuffle each row independently
col_ind = np.argsort(np.random.random(result.shape), axis=1)
row_ind = np.arange(m).reshape(-1, 1)
# perform the shuffle
result = result[row_ind, col_ind]
return result