Python 2.7内存错误,大复杂性

时间:2012-01-26 15:02:57

标签: python dictionary

我是python的新手。我运行以下代码,它给python2.7带来内存错误。 因为我使用的是opencv,所以我正在使用python2.7。我已阅读过以前的帖子,但我对他们的理解不多。

s={}
ns={}
ts={}
for i in range(0,256): #for red component
    for j in range(0,256): #for green component
        for k in range(0,256): # for blue component
            s[(i,j,k)]=0
            ns[(i,j,k)]=0
            ts[(i,j,k)]=i*j*k

请帮忙。代码尝试存储红色,绿色和蓝色组件的频率。为此,我将这些值初始化为零

3 个答案:

答案 0 :(得分:5)

事1:使用itertools而不是每次循环构建所有range列表。 xrange将返回一个迭代器对象,如rangeproduct将返回一个迭代器,选择给定迭代中元素的元组。

事情2:对大数据使用numpy。它是为这类事物设计的矩阵实现。

>>> import numpy as np
>>> from itertools import product
>>> x=np.zeros((256,256,256))
>>> for i, j, k in product(xrange(256), repeat=3):
...     x[i,j,k]= i*j*k
... 

对我来说需要大约五秒钟,以及预期的内存量。

$ cat /proc/27240/status 
Name:   python
State:  S (sleeping)
...
VmPeak:   420808 kB
VmSize:   289732 kB

请注意,如果尝试分配三个256 * 256 * 256阵列,实际上可能会遇到系统范围的内存限制,因为每个阵列都有大约1700万个条目。幸运的是,numpy允许您将数组保存到磁盘。

你遇到过PIL (Python Imaging Library)吗?你可能会发现它很有帮助。

答案 1 :(得分:1)

事实上,您的程序至少需要(!)300 * 300 * 300 * 4 * 3字节,仅用于dicts的值数据。此外,您的密钥元组占用300 * 300 * 300 * 3 * 3 * 4字节。

总共1296000000字节,或1.2 GiB数据。

此计算甚至不包括在dict中维护数据的开销。

因此,它取决于机器在发生故障时的内存量。

你可以做第一步并做

s = {}
ns = {}
ts = {}
for i in range(0, 300):
    for j in range(0, 300):
        for k in range(0, 300):
            index=(i, j, k)
            s[index]=j
            ns[index]=k
            ts[index]=i*j*k

(理论上)只占用内存的一半 - 同样,仅用于数据,因为索引元组被重用。


根据您的描述(您只想计算),您不需要预先初始化所有组合。因此,您可以省略问题中显示的初始化,而是构建一个存储空间,您只将这些值存储在实际拥有数据的位置,这些数据应该比可能的数据少得多。

您可以使用defaultdict()或手动模仿其行为,因为我认为大多数组合都没有在您的颜色“调色板”中使用。

from collections import defaultdict
make0 = lambda: 0
s = defaultdict(make0)
ns = defaultdict(make0)
# what is ts? do you need it?

现在你有三个dict - 类似的对象,如果需要可以写入。然后,对于你真正拥有的每种颜色组合,你可以s[index] += 1 resp。 ns[index] += 1

我不知道你的ts - 或许你可以计算它,或者你必须找到不同的解决方案。

答案 2 :(得分:0)

即使所有变量都使用单个字节,该程序也需要405 MB的RAM。

您应该使用压缩来在有限的空间内存储更多内容。

编辑:如果你想在Python中制作直方图,see this nice example of using the Python Image Library (PIL)。用这3行完成了艰苦的工作:

import Image
img = Image.open(imagepath)
hist = img.histogram()