在Python和NumPy中处理大数据时,内存不足,如何将部分结果保存到磁盘上?

74

我正在尝试使用Python实现针对具有200k+数据点的1000维数据的算法。我想使用numpy、scipy、sklearn、networkx和其他有用的库。我想要执行一些操作,例如所有点之间的成对距离,并在所有点上进行聚类。我已经实现了可以按照我想要的方式执行工作的算法,并且复杂度合理,但是当我尝试将它们扩展到所有数据时,就会耗尽内存。当然,这是可以理解的,因为在200k+数据上创建成对距离矩阵需要大量内存。

问题来了:我真的很想在RAM较低的烂电脑上完成这项工作。

有没有可行的方法让我在没有低RAM限制的情况下工作?花费更长的时间并不是问题,只要时间要求不无穷大!

我希望能够让我的算法开始工作,然后在一个小时或五个小时后回来,而不会出现因为内存不足而卡住的情况!我想在Python中实现这一点,并能够使用numpy、scipy、sklearn和networkx库。我也希望能够计算所有点的成对距离等。

这可行吗?我该怎么做?我可以从哪些方面开始阅读资料?


5
我希望能在Python中执行针对一个200,000 x 1000矩阵中所有点的配对距离,但是我的内存不够大无法把整个距离矩阵保存在内存中。我正在寻找关于如何做到这一点的信息 :) 因此,比模糊的“查看计算机科学的两个子领域”更具体的答案会更有帮助! - Ekgren
8
你可能想要查看numpy的memmap,并且可能需要以PyTables作为起点。 - Henry Gomersall
从下面的第一个相关问题中,用户@cronos建议使用h5py,我相信它也可以用于您的问题。1-是否可能将内存映射文件np.concatenate? 2-连接Numpy数组而不复制 - Saullo G. P. Castro
1个回答

98

使用numpy.memmap,可以直接创建映射到文件的数组:

import numpy
a = numpy.memmap('test.mymemmap', dtype='float32', mode='w+', shape=(200000,1000))
# here you will see a 762MB file created in your working directory    
你可以将它视为常规数组: a += 1000。
如果需要,甚至可以将更多的数组分配给同一个文件,并且从相互的来源控制它。但是在这里我经历了一些棘手的事情。要打开完整的数组,您必须首先使用del“关闭”前一个数组:
del a    
b = numpy.memmap('test.mymemmap', dtype='float32', mode='r+', shape=(200000,1000))

但是只打开数组的一部分可以实现同时控制:

b = numpy.memmap('test.mymemmap', dtype='float32', mode='r+', shape=(2,1000))
b[1,5] = 123456.
print a[1,5]
#123456.0

太棒了!ab一起被更改了。并且更改已经写入磁盘。

另一个值得评论的重要事情是offset。假设你想取出b中不是前两行,而是第150000行和第150001行。

b = numpy.memmap('test.mymemmap', dtype='float32', mode='r+', shape=(2,1000),
                 offset=150000*1000*32/8)
b[1,2] = 999999.
print a[150001,2]
#999999.0

现在,您可以同时访问和更新数组的任何部分。请注意进行偏移计算时的字节大小。因此,对于“float64”类型,此示例将是150000 * 1000 * 64/8。

其他参考资料:


2
抱歉,我不明白你做了什么。你是否使用“w+”创建了一个名为“test.mymemmap”的文件,并通过将变量“a”赋值到内存中进行了存储。但是然后你又删除了它,然后使用“r+”读取文件并存储在变量“b”中。我不确定你做了什么。我有一个名为“myfile.npy”的大文件,我想分批读取它... - Marlon Teixeira
在使用memmaps时,我们需要注意任何隐藏的问题吗?是否可以像简单的numpy数组一样执行操作? - seralouk
1
据我所知,这是没问题的。你应该仔细考虑内存布局以及如何使用“偏移量”参数来访问数组的正确位置。 - Saullo G. P. Castro
@SaulloG.P.Castro 谢谢。我总是使用完整的矩阵(我不会对其进行切片),所以在我的情况下应该没问题。 - seralouk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接