Python 如何使用大型阵列防止大量使用RAM?

Python 如何使用大型阵列防止大量使用RAM?,python,arrays,numpy,ram,Python,Arrays,Numpy,Ram,一个文件为我提供了一个400x400x200x1数组和一个形状。根据阵列传输的数据,形状会发生变化。我的任务是使400x400x200x1阵列适应其包含的数据。 例如: shape = np.array([20,180,1,1]) b= [] l = np.load("testfile.npy") d = (np.reshape(l[:shape[0],:shape[1],:shape[2],:shape[3]],(shape[0],sha

一个文件为我提供了一个400x400x200x1数组和一个形状。根据阵列传输的数据,形状会发生变化。我的任务是使400x400x200x1阵列适应其包含的数据。
例如:

shape = np.array([20,180,1,1])
b= []                            
l = np.load("testfile.npy")
d = (np.reshape(l[:shape[0],:shape[1],:shape[2],:shape[3]],(shape[0],shape[1]))).transpose()
append(d)
其想法是创建一个新的数组,其大小与数据相适应。 现在问题来了:我必须多次执行此过程,但每次执行时,我的RAM负载系数都会增加

shape = np.array([20,180,1,1])
b= []                            
for j in range(9):
  l = np.load("testfile.npy")
  d = (np.reshape(l[:shape[0],:shape[1],:shape[2],:shape[3]],(shape[0],shape[1]))).transpose()
  time.sleep(2)
  b.append(d)

这仅仅是因为appendet数组太大了吗?我附加的输出数组大小为180x20。。。但是RAM负载系数每次增加0,12GB。有没有更有效的方法来存储阵列而不使用临时文件


感谢并为我的英语感到抱歉。

您的大部分RAM使用来自将整个400x400x200x1阵列读入内存。告诉numpy内存映射输入数组,它应该能够避免读取其中的大部分:

l = np.load("testfile.npy", mmap_mode='r')
由于
重塑
转置
都会尽可能返回原始数组的视图,因此也值得显式复制结果。我们还可以简化索引:

d = l[:20, :180, 0, 0].transpose().copy()

我认为您选择的特定索引不允许NumPy返回视图,但当它返回视图时,视图将导致保留整个原始数组。对于内存映射数组,我相信视图也将是内存映射的,这可能不是您想要的。

在您的示例中,您的错误是在For循环的每次迭代中重新加载文件。 尝试:

这就解决了问题

现在,原因是什么:在每次从文件加载
l
时,隐式地在部分(
d
)上创建一个
视图,并将该视图添加到
b
。视图实际上包含对整个数组的引用。因此,每次加载整个数组并存储一个引用该数组的对象,从而禁用垃圾收集器以释放内存

如果出于任何原因每次都必须重新加载文件,另一种解决方案是显式创建副本,以丢失对整个数组的引用。在您的示例中,将最后一行替换为:

b.append(d.copy())
注1:实际上,由于视图
d
的大小与
l
相比可以忽略不计,因此您应该始终制作一份副本

注2:要断言
d
保留对
l
的引用,您可以

d.base.base.base is l # True

.base
是对已查看阵列的引用。在您的例子中有3种深度:
l[…]
切片、重塑和转置。

当从函数返回大数组时,如何使用numpy.memmap?e、 g.
bigarray=函数赋予sbigarray()
?谢谢@你很可能不能。函数通常需要提供一个内存映射选项。在我的例子中,大数组来自一个函数,随着数据的变化,我必须用新数据重新加载函数。你的第二个建议解决了我的问题。谢谢!
d.base.base.base is l # True