Python/Numpy MemoryError

tyl*_*ler 23 python memory numpy scipy

基本上,当我尝试在numpy矩阵上执行代数运算时,我在python中遇到内存错误.变量u,是一个双倍的大矩阵(在失败的情况下,它是一个288x288x156的双倍矩阵.我只在这个巨大的情况下得到这个错误,但我能够在其他大型矩阵上做到这一点,只是不是这么大).这是Python错误:

 Traceback (most recent call last):

 File "S:\3D_Simulation_Data\Patient SPM Segmentation\20 pc
t perim erosion flattop\SwSim.py", line 121, in __init__
   self.mainSimLoop()

 File "S:\3D_Simulation_Data\Patient SPM Segmentation\20 pc
t perim erosion flattop\SwSim.py", line 309, in mainSimLoop
   u = solver.solve_cg(u,b,tensors,param,fdHold,resid) # Solve the left hand si
de of the equation Au=b with conjugate gradient method to approximate u

 File "S:\3D_Simulation_Data\Patient SPM Segmentation\20 pc
t perim erosion flattop\conjugate_getb.py", line 47, in solv
e_cg

u = u + alpha*p

MemoryError
Run Code Online (Sandbox Code Playgroud)

u = u + alpha*p 是失败的代码行.

alpha只是一个双倍,u而且r是上面描述的大矩阵(两者都是相同的大小).

我对内存错误知之甚少,特别是在Python中.任何有关解决此问题的见解/提示都将非常感激!

谢谢

lui*_*dro 48

改写为

p *= alpha
u += p
Run Code Online (Sandbox Code Playgroud)

这将使用更少的内存.而p = p*alpha为结果分配一个全新的矩阵p*alpha,然后丢弃旧的p; p*= alpha做同样的事情.

通常,对于大矩阵,请尝试使用op=赋值.


Dav*_*veP 11

我发现避免内存错误的另一个技巧是手动控制垃圾收集.当删除对象或使用我们的范围时,在执行垃圾收集之前,不会释放用于这些变量的内存.我发现我的一些代码使用了大型的numpy数组,我得到了一个MemoryError,但是如果我在适当的地方插入对gc.collect()的调用,我可以避免这种情况.

如果使用"op ="样式运算符等不能解决您的问题,您应该只考虑此选项,因为它可能不是最好的编码实践,让gc.collect()调用到处.

  • @endolith的原因与你的`malloc()`失败时你不能暂停和清理内存一样 - 它已经太晚了_already_失败了.然后你可以加倍回复,GC再试一次,但我认为NumPy开发人员宁愿你修复代码而不是依靠创可贴. (2认同)

Ben*_*ier 6

你的矩阵有288x288x156 = 12,939,264个条目,double内存可能达到400MB.numpy抛出一个MemoryError只是意味着在操作系统中无法提供执行操作所需的内存.

如果您可以使用稀疏矩阵,这可能会为您节省大量内存.

  • 但我的电脑有24GB的内存...有没有办法确保更多可用的窗口?编辑:我们正在使用的python的版本是32位由于某种原因:/ Edit2:不幸的是,稀疏矩阵不是一个选项,因为所有元素都有值(热方程像问题). (2认同)