运行Numpy阵列操作时减少内存使用量

时间:2019-09-24 11:00:34

标签: python arrays numpy

我有一个相当大的NumPy数组,我需要对它执行操作,但是当我这样做时,我的〜2GB数组需要〜30GB的RAM才能执行该操作。我已经读过NumPy可能在内存使用方面相当笨拙,但这似乎过多。

有人知道应用这些操作来限制RAM负载的另一种方法吗?也许逐行/就地等?

下面的代码(忽略无意义的计算,在我的代码中,系数各不相同):

import xarray as xr 
import numpy as np

def optimise(data):

    data_scaled_offset = (((data - 1000) * (1 / 1)) + 1).round(0)
    return data_scaled_offset.astype(np.uint16)

# This could also be float32 but I'm using uint16 here to reduce memory load for demo purposes
ds = np.random.randint(0, 12000, size=(40000,30000), dtype=np.uint16)

ds = optimise(ds) # Results in ~30GB RAM usage

2 个答案:

答案 0 :(得分:2)

通过默认操作,如乘法,加法和许多其他操作,您可以使用numpy.multiply,numpy.add并使用out参数来使用现有数组来存储结果。这将大大减少内存使用量。请查看下面的演示并翻译您的代码以改用这些功能

arr = np.random.rand(100)
arr2 = np.random.rand(100)

arr3 = np.subtract(arr, 100, out=arr)
arr4 = arr+100
arr5 = np.add(arr, arr2, out=arr2)
arr6 = arr+arr2

print(arr is arr3) # True
print(arr is arr4) # False
print(arr2 is arr5) # True
print(arr2 is arr6) # False

答案 1 :(得分:2)

您可以使用例如。 Numba或Cython可减少内存使用。 当然也可以进行简单的Python循环,但速度非常慢。

已分配输出数组

import numpy as np
import numba as nb

@nb.njit()
def optimise(data):
    data_scaled_offset=np.empty_like(data)
    # Inversely apply scale and scale and offset for this product
    for i in range(data.shape[0]):
        for j in range(data.shape[1]):
            data_scaled_offset[i,j] = np.round_((((data[i,j] - 1000) *(1 / 1)) + 1),0)

    return data_scaled_offset

就地

@nb.njit()
def optimise_in_place(data):
    # Inversely apply scale and scale and offset for this product
    for i in range(data.shape[0]):
        for j in range(data.shape[1]):
            data[i,j] = np.round_((((data[i,j] - 1000) *(1 / 1)) + 1),0)

    return data