我正在处理一个大矩阵(250x250x30=1875000个单元格),我想用一种方法为这个矩阵中的每个单元格设置任意数量的标志,这种方法使用简单,而且节省空间。
我最初的计划是一个250x250x30列表数组,其中的每个元素都类似于:["FLAG1","FLAG8","FLAG12"]
。然后我将它改为只存储整数:[1,8,12]
。这些整数由getter/setter函数内部映射到原始标志字符串。这只使用250mb,每个点有8个标志,这在内存方面是很好的。
我的问题是:我是否遗漏了另一种构造此类数据的明显方法?
谢谢大家的建议。最后,我把一些建议整合成一个,可惜我只能选择一个答案,而不得不接受对其他答案的投票:
编辑:呃,我这里的初始代码(使用集合作为3d numpy数组的基本元素)使用了大量内存。这个新版本在填充randint(0,2**1000)
时使用大约500mb。
import numpy
FLAG1=2**0
FLAG2=2**1
FLAG3=2**2
FLAG4=2**3
(x,y,z) = (250,250,30)
array = numpy.zeros((x,y,z), dtype=object)
def setFlag(location,flag):
array[location] |= flag
def unsetFlag(location,flag):
array[location] &= ~flag
您可以用两个值的不同幂定义一些常数:
并将它们与布尔逻辑一起使用,以仅将标志存储在一个整数中,p.e.:
要检查是否启用了标志,可以使用
&
运算符:如果启用该标志,则此表达式将返回一个非零值,在任何布尔操作中该值都将被计算为True。如果该标志被禁用,表达式将返回0,在布尔操作中该值被计算为False。
如果每个单元都有一个标志,那么你的解决方案是好的。但是,如果您使用的是稀疏数据集,其中只有一小部分单元格具有标记,那么您真正需要的是字典。您需要设置dictional,以便键是单元格位置的元组,值是解决方案中的标志列表。
这里我们有1,1,1单元格有标志1,2和3,250250,30单元格有标志4,5和6
编辑-固定键元组,谢谢安德烈,和字典语法。
我通常使用一个numpy数组(可能是短整型,每个2字节,因为您可能需要超过256个不同的值),对于200万个单元格来说,这个数组的大小不到4MB。
如果出于某种原因,我负担不起numpy依赖性(例如在App Engine上,它不支持numpy),我会使用标准库array模块-它只支持一维数组,但对于大型同构数组,它与numpy一样节省空间,而且您提到的getter/setter例程可以很好地“线性化”一个3项元组,这是您的自然索引到一维数组的单个整数索引中。
一般来说,当您有大量的同质的、密集的向量或数字矩阵时,请考虑numpy(或数组)——在这个用例中,Python内置列表非常浪费空间(由于它们的通用性,您不需要也不需要在这里使用它们!)!-),而节省内存也间接地转化为节省时间(更好的缓存、更少的间接寻址级别等)。
相关问题 更多 >
编程相关推荐