Noo*_*bot 20 python arrays optimization memory-management numpy
有时您必须在一个或多个大型Numpy阵列上执行许多中间操作.这很快就会导致MemoryError
s.在我迄今为止的研究中,你发现Pickling(Pickle,CPickle,Pytables等)并且gc.collect()
是减轻这种情况的方法.我想知道在处理大量数据时是否还有其他有经验的程序员使用的技术(当然,除了删除策略/代码中的冗余).
另外,如果有一点我确定没有什么是免费的.使用其中一些技术,有什么权衡(即速度,稳健性等)?
Jai*_*ime 22
我感觉到你的痛苦...你有时最终会以你后来丢弃的值存储数组大小的几倍.在一次处理数组中的一个项目时,这是无关紧要的,但在向量化时会杀死你.
我将使用工作中的示例进行说明.我最近用numpy 编写了这里描述的算法.它是一种彩色图算法,它采用RGB图像,并将其转换为CMYK图像.对每个像素重复的过程如下:
你可以做几件事来处理这件事:
也许你不能在一次通过中处理1,000x1,000阵列.但是如果你可以用python for循环迭代10个100x1,000的数组,那么它仍然会超过1,000,000个项目的python迭代器!它会变慢,是的,但不是那么多.
这与我上面的插值示例直接相关,并且更难以遇到,尽管值得关注它.因为我在每个维度上有4位的三维立方体进行插值,所以只有16x16x16可能的结果,可以存储在16个16x16x16字节的数组中.所以我可以预先计算它们并使用64KB的内存来存储它们,并逐个查找整个图像的值,而不是以巨大的内存成本为每个像素重做相同的操作.这已经为小到64x64像素的图像付出了代价,并且基本上允许处理图像数量为x6倍的图像而无需细分数组.
dtypes
明智地使用你如果您的中间值可以适合单个uint8
,请不要使用int32
s 数组!由于无声溢出,这可能会变成神秘错误的噩梦,但如果你小心,它可以节省大量资源.
第一个最重要的技巧:分配几个大数组,并使用和回收它们的一部分,而不是带来生命和丢弃/垃圾收集大量的临时数组.听起来有点过时,但仔细编程加速可能会令人印象深刻.(您可以更好地控制对齐和数据位置,因此可以提高数字代码的效率.)
第二:使用numpy.memmap
并希望操作系统对磁盘的访问缓存足够高效.
第三:正如@Jaime所指出的那样,如果整个矩阵是大的,则工作un块子矩阵.
编辑:
如SE 中的答案所指出的那样,避免不必要的列表理解.
归档时间: |
|
查看次数: |
15959 次 |
最近记录: |