我有一个相当大的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
答案 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