我想生成一个随机的二进制矩阵,所以我使用W=np.random.binomial(1, p, (n,n))
,它运行得很好,但是我需要一个约束,即没有一行是0。
我创建以下函数:
def random_matrix(p,n):
m=0
while m==0:
W = np.random.binomial(1, p, (n,n))
m=min(W.sum(axis=1))
return W
它也工作得很好,但在我看来效率太低了。有没有更快的方法来创建这个约束?
2条答案
按热度按时间0md85ypi1#
一种使生成不包含仅为0的行的随机二进制矩阵的过程更有效的方法是使用np.random.choice函数从矩阵的每行随机选择非零项并将其值设置为1。这避免了使用while循环和重复检查仅为0的行的需要,对于大型矩阵,这可能会导致计算开销很大。
下面是一个示例,说明如何使用np.random.choice函数生成一个随机二进制矩阵,其中没有只包含0的行:
jv2fixgn2#
当矩阵很大时,仅因为少数数据列全是零,就重新产生整个矩阵的效率并不高。只重新产生目的数据列,在统计上应该是安全的。范例如下:
更快的解决方案
当
p
接近0时,有一种更有效的方法(当p
接近1时,则上述函数已经是快的)。实际上,具有0-1个值的二项式随机变量是伯努利随机变量。具有概率p的伯努利随机值重复多次的和是二项式随机值!因此,您可以使用S = np.random.binomial(n, p, (n,n))
生成所有行的总和,然后应用上述方法来去除空值,然后通过为第i行生成x1M3 N1 x1值并使用x1M4 N1 x50来随机化每行中0-1值的顺序来构建最终矩阵。这种方法解决冲突的效率比其他所有方法都要高得多。实际上,它不需要生成整行来检查它是否充满零。解决冲突的速度快了n
倍!如果这还不够,可以使用
uint8
数据类型来生成W
。实际上,内存很慢,所以生成较小的矩阵通常更快,更不用说它占用的RAM更少。如果这还不够,你可以使用Numba JIT编译器和一个基本循环为每个项目生成
S
个项目。这应该会更快,因为除了最后一个,没有临时数组要创建。对于大型矩阵,这个算法甚至可以并行化(每行都可以独立生成)。最后一个解决方案应该接近最优。