我有一个601x350x200x146
numpy float64
数组,根据我的计算,它会占用大约22.3 Gb的内存。我的free -m
输出告诉我,我有大约100Gb的可用内存,所以它很合适。但是,与
result = np.trapz(large_arr, axis=3)
我收到内存错误。我知道这是因为numpy.trapz
必须创建的中间数组才能执行集成。但是我想看看它是否有办法,或者至少是一种最小化额外内存使用的方法。
我已经阅读了有关内存错误的内容,并且我知道要避免这种情况的事情:一个是在集成之前发出gc.collect()
调用。我尝试了这个并没有用。
另一个是使用*=
运算符,例如编写arr*=a
而不是arr=arr*a
,我在这里无法真正做到。所以我不知道还有什么可以尝试。
有没有人知道如何在不引起内存错误的情况下执行此操作?
您可以使用以下内容重现错误:
arr = np.ones((601,350,200,146), dtype=np.float64)
arr=np.trapz(arr, axis=3)
虽然您必须缩小尺寸以匹配您的内存大小。
答案 0 :(得分:3)
numpy.trapz
提供了一些便利,但实际计算非常简单。要避免使用大型临时数组,请自行实现:
In [37]: x.shape
Out[37]: (2, 4, 4, 10)
这是numpy.trapz(x, axis=3)
:
In [38]: np.trapz(x, axis=3)
Out[38]:
array([[[ 43. , 48.5, 46.5, 67. ],
[ 35.5, 39.5, 52.5, 35. ],
[ 44.5, 47.5, 34.5, 39.5],
[ 54. , 40. , 46.5, 50.5]],
[[ 42. , 60. , 55.5, 51. ],
[ 51.5, 40. , 52. , 42.5],
[ 48.5, 43. , 32. , 36.5],
[ 42.5, 38. , 38. , 45. ]]])
这里是为了使用 no 大型中间数组而编写的计算。 (切片x[:,:,:,1:-1]
不会复制与数组关联的数据。)
In [48]: 0.5*(x[:,:,:,0] + 2*x[:,:,:,1:-1].sum(axis=3) + x[:,:,:,-1])
Out[48]:
array([[[ 43. , 48.5, 46.5, 67. ],
[ 35.5, 39.5, 52.5, 35. ],
[ 44.5, 47.5, 34.5, 39.5],
[ 54. , 40. , 46.5, 50.5]],
[[ 42. , 60. , 55.5, 51. ],
[ 51.5, 40. , 52. , 42.5],
[ 48.5, 43. , 32. , 36.5],
[ 42.5, 38. , 38. , 45. ]]])
如果x
的形状为(m, n, p, q)
,则该表达式中生成的少数临时数组的形状都为(m, n, p)
。