将大型数组与Numpy集成时,避免内存错误

时间:2016-12-16 21:07:33

标签: python arrays numpy out-of-memory

我有一个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)

虽然您必须缩小尺寸以匹配您的内存大小。

1 个答案:

答案 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)