Python 使用numpy创建大型随机布尔矩阵

Python 使用numpy创建大型随机布尔矩阵,python,numpy,random,Python,Numpy,Random,我试图创建一个巨大的布尔矩阵,该矩阵随机填充真和假,概率为p。首先,我使用了以下代码: N = 30000 p = 0.1 np.random.choice(a=[False, True], size=(N, N), p=[p, 1-p]) 但不幸的是,它似乎并没有因为这么大的N而终止。因此,我尝试通过以下操作将其拆分为单行: N = 30000 p = 0.1 mask = np.empty((N, N)) for i in range (N): mask[i] = np.ra

我试图创建一个巨大的
布尔
矩阵,该矩阵随机填充
,概率为
p
。首先,我使用了以下代码:

N = 30000
p = 0.1
np.random.choice(a=[False, True], size=(N, N), p=[p, 1-p])  
但不幸的是,它似乎并没有因为这么大的
N
而终止。因此,我尝试通过以下操作将其拆分为单行:

N = 30000
p = 0.1
mask = np.empty((N, N))
for i in range (N):
     mask[i] = np.random.choice(a=[False, True], size=N, p=[p, 1-p])            
     if (i % 100 == 0):
          print(i)
现在,发生了一些奇怪的事情(至少在我的设备上):第一~1100行的生成速度非常快,但之后,代码变得非常慢。为什么会这样?我错过了什么?有没有更好的方法来创建一个大矩阵,其中包含概率
p
True
条目和概率
1-p
False
条目


编辑:很多人都认为RAM会有问题:因为运行代码的设备几乎有500GB的RAM,所以这不会是问题。

问题是您的RAM,在创建时,这些值会存储在内存中。我刚刚使用以下命令创建了此矩阵:

np.random.choice(a=[False,True],size=(N,N),p=[p,1-p])

我使用了一个带有64GB RAM和8个内核的AWSI3实例。要创建此矩阵,
htop
显示它占用约20GB的RAM。以下是一个基准,以防您在意:

time np.random.choice(a=[False, True], size=(N, N), p=[p, 1-p])

CPU times: user 18.3 s, sys: 3.4 s, total: 21.7 s
Wall time: 21.7 s


 def mask_method(N, p):
    for i in range(N):
        mask[i] = np.random.choice(a=[False, True], size=N, p=[p, 1-p])
        if (i % 100 == 0):
            print(i)

time mask_method(N,p)

CPU times: user 20.9 s, sys: 1.55 s, total: 22.5 s
Wall time: 22.5 s
请注意,掩码方法在其峰值仅占用约9GB的RAM


编辑:第一种方法在处理完成后刷新RAM,其中函数方法保留所有RAM。

另一种可能是成批生成RAM(即计算多个子数组并将它们堆叠在一起)。但是,不要考虑更新一个数组(<代码>掩码< /代码>)。这将迫使在每次索引更新期间将整个数组加载到主内存中

例如:要获得
30000x30000
,让9000个
100x100
单独的数组,在
for
循环中相应地更新每个
100x100
数组,最后将这9000个数组堆叠在一个巨大的数组中。这肯定不需要超过4GB的RAM,而且速度也非常快

最简单的例子:

In [9]: a
Out[9]: 
array([[0, 1],
       [2, 3]])

In [10]: np.hstack([np.vstack([a]*5)]*5)
Out[10]: 
array([[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
       [2, 3, 2, 3, 2, 3, 2, 3, 2, 3],
       [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
       [2, 3, 2, 3, 2, 3, 2, 3, 2, 3],
       [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
       [2, 3, 2, 3, 2, 3, 2, 3, 2, 3],
       [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
       [2, 3, 2, 3, 2, 3, 2, 3, 2, 3],
       [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
       [2, 3, 2, 3, 2, 3, 2, 3, 2, 3]])

In [11]: np.hstack([np.vstack([a]*5)]*5).shape
Out[11]: (10, 10)
因此,我尝试通过以下操作将其拆分为单行:

np.random.choice
的工作方式是首先在
[0,1)
中为数据的每个单元格生成一个
float64
,然后使用
np.search\u sorted
将其转换为数组中的索引。这个中间表示比布尔数组大8倍

由于您的数据是布尔型的,因此使用

np.random.rand(N, N) > p
当然,您可以在循环解决方案中使用

似乎
np.random.choice
可以在这里进行一些缓冲-您可能希望针对numpy提交一个问题


另一种选择是尝试生成
float32
s,而不是
float64
s。我不确定numpy现在是否可以这样做,但您可以请求该功能。

无法理解该部分-
似乎不会因为这个大N
而终止。对此进行了澄清?为什么使用布尔数组但不设置数据类型?以及如果您的内存足够,请检查III。否则,垃圾处理会减慢每种方法的速度。一旦内存耗尽,它会减慢机器的速度?@Serge但为什么?我的意思是:我正在第3行创建NxN数组-因此没有理由让内存耗尽。此外,内存确实没有问题,因为机器中有很多内存-大约0.5 TB。@FlashTek:在你写之前,你的操作系统实际上不会把RAM分配给它。好吧,有趣的是,
np.random.rand(N,N)的解决方案>p
是我的第一个想法,我放弃了这个想法,因为我认为直接numpy调用会更快。@FlashTek:问题是
np.random.choice
需要做更多的工作,因为它必须处理两个以上结果的情况。当选择的数量是两个时,一定要考虑特殊情况。但是你知道为什么会这样吗在我的第一篇博文中发生了多少次减速?哪种减速?你第二次尝试的速度更快的原因是因为你没有一次分配所有的浮动,而且它们比你的最终结果大得多。不,我是说第二次尝试的减速发生在第1100行生成之后-如上所述。