我有一个二进制 numpy 矩阵,我想随机关闭 30% 的矩阵,其中关闭 30% 意味着用 0 替换 30% 的 1。一般来说,我想这样做很多次,所以如果我这样做 5 次,我希望最终矩阵有 100*(1-0.3)^5 = 16% 的原始矩阵,最初都是 1。
重要的是我想关闭 30% 的活动位(一),而不是关闭整个矩阵的 30%(一和零,关闭零只是零)。
我想出了一个方法来做到这一点,但它似乎没有实现上述目标,因为在关闭 30% 的 5 个会话之后,矩阵是 23% 1s 而不是 16% 1s。
为了通过示例进行说明,我的方法如下:
>>> mask=np.array([[1,1,1,1,1],[1,1,1,0,0],[1,1,0,0,0]])
>>> mask
array([[1, 1, 1, 1, 1],
[1, 1, 1, 0, 0],
[1, 1, 0, 0, 0]])
>>> np.where(mask==0, np.zeros_like(mask), mask * np.random.binomial(1, 0.7, mask.shape))
array([[1, 1, 1, 0, 0],
[0, 1, 1, 0, 0],
[1, 1, 0, 0, 0]])
上面的代码给出了一个新矩阵,如果一个位为 0,则保持为 0,如果为 1,则在 30% 的时间内关闭。
在这个小例子中,一切似乎都很好,因为我已经删除了 30% 的那些(我有 10 个,现在我有 7 个)。但我认为我的方法不能很好地推广到大型矩阵。我相信这是由于以下原因:
尽管 Bernoulli 试验应该是相互独立的,但 numpy 可能会试图确保总体而言,所有试验中有 30% 是 Tails。但是在我的代码中,“所有试验”等于整个矩阵的大小,而不是矩阵中的数量,这就是导致问题的原因。
什么是清除 30% 的活动位而不是 30% 的所有位的一种干净的 Python 方式?