在 python 和 numpy 中处理大数据,没有足够的内存,如何将部分结果保存在磁盘上?
Posted
技术标签:
【中文标题】在 python 和 numpy 中处理大数据,没有足够的内存,如何将部分结果保存在磁盘上?【英文标题】:Working with big data in python and numpy, not enough ram, how to save partial results on disc? 【发布时间】:2013-04-22 14:36:25 【问题描述】:我正在尝试在 python 中实现具有 200k+ 数据点的 1000 维数据的算法。我想使用 numpy、scipy、sklearn、networkx 和其他有用的库。我想执行诸如所有点之间的成对距离之类的操作,并对所有点进行聚类。我已经实现了以合理复杂性执行我想要的工作的算法,但是当我尝试将它们扩展到我的所有数据时,我的 RAM 用完了。当然,我愿意,为 200k+ 数据创建成对距离矩阵会占用大量内存。
问题来了:我真的很想在内存不足的蹩脚计算机上执行此操作。
有没有可行的方法让我不受低 RAM 限制的情况下完成这项工作?这将花费更长的时间真的不是问题,只要时间要求不至无穷大!
我希望能够让我的算法运行起来,然后在一五个小时后返回,而不是因为内存不足而卡住!我想在 python 中实现它,并且能够使用 numpy、scipy、sklearn 和 networkx 库。我希望能够计算到我所有点的成对距离等
这可行吗?我该怎么做,我可以开始阅读什么?
【问题讨论】:
我希望能够在 python 中执行 200.000 x 1000 矩阵中所有点之间的成对距离,而无需足够的内存来将整个距离矩阵保存在内存中。我正在寻找有关如何做到这一点的信息:) 所以更具体的答案然后模糊的“研究计算机科学的两个完整子领域”会有所帮助! 您可能想看看 numpy 的 memmap 和可能的 PyTables 作为起点。 从下面的第一个相关问题用户@cronos 建议到useh5py
,我相信它也可以用于您的问题。 1-Is it possible to np.concatenate memory-mapped files? 2-Concatenate Numpy arrays without copying
【参考方案1】:
使用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
太棒了! a
与 b
一起更改。并且更改已经写入磁盘。
另一个值得评论的重要事情是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。
其他参考资料:
Is it possible to map a discontiuous data on disk to an array with python?
numpy.memmap
documentation here.
【讨论】:
对不起,我不明白你做了什么。您是否使用“w+”创建了一个名为“test.mymemmap”的文件,您通过分配变量“a”将其存储到内存中。但是你已经删除了它,然后使用'r +'读取文件并存储在变量'b'中。我不确定你做了什么。我有一个名为“myfile.npy”的大文件,我想分批读取它... 在使用 memmap 时,我们应该注意哪些隐藏的事情?像简单的 numpy 数组这样的操作可以吗? @seralouk 据我所知很好。您应该仔细考虑内存布局以及如何使用offset
参数来访问数组的正确位置。
@SaulloG.P.Castro 谢谢。我总是使用完整的矩阵(我不切片)所以在我的情况下应该没问题。以上是关于在 python 和 numpy 中处理大数据,没有足够的内存,如何将部分结果保存在磁盘上?的主要内容,如果未能解决你的问题,请参考以下文章