Python中的标志

Ale*_*x J 4 python flags numpy matrix

我正在使用一个大矩阵(250x250x30 = 1,875,000个单元格),我想要一种方法为这个矩阵中的每个单元设置任意数量的标志,这种方式易于使用且空间效率合理.

我最初的计划是一个250x250x30列表数组,其中每个元素都是这样的:["FLAG1","FLAG8","FLAG12"].然后我将其改为仅存储整数:[1,8,12].这些整数由getter/setter函数在内部映射到原始标志字符串.这仅使用250mb,每点8个标志,这在内存方面很好.

我的问题是:我是否错过了构建此类数据的另一种明显方法?

谢谢大家的建议.我最后将一些建议合而为一,遗憾的是,我只能选择一个答案而不得不与其他人一起生活:

编辑:我在这里使用的初始代码(使用集合作为3d numpy数组的基本元素)使用了大量内存.这个新版本在填充时使用大约500mb randint(0,2**1000).

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
Run Code Online (Sandbox Code Playgroud)

Rob*_*bie 7

如果每个单元格都有标记,那么您的解决方案就可以了.但是,如果您正在使用稀疏数据集,其中只有一小部分单元格会有标记您真正想要的是字典.您可能希望设置dictonary,因此键是单元格位置的元组,值是您在解决方案中的标记列表.

allFlags = {(1,1,1):[1,2,3], (250,250,30):[4,5,6]}
Run Code Online (Sandbox Code Playgroud)

这里我们有1,1,1单元有标志1,2和3,单元250,250,30有标志4,5和6

编辑 - 修复关键元组,谢谢安德烈和字典语法.


Jai*_*ano 5

您可以使用两个值的不同幂来定义一些常量:

FLAG1 = 0x01
FLAG8 = 0x02
FLAG12 = 0x04
...
Run Code Online (Sandbox Code Playgroud)

并使用布尔逻辑将它们存储在一个整数中,pe:

flags = FLAG1 | FLAG8
Run Code Online (Sandbox Code Playgroud)

要检查是否启用了标志,您可以使用&运算符:

flag1_enabled = flags & FLAG1
Run Code Online (Sandbox Code Playgroud)

如果启用该标志,则此表达式将返回非零值,该值将在任何布尔运算中计算为True.如果禁用该标志,则表达式将返回0,在布尔运算中将其计算为False.


Ale*_*lli 5

我通常会使用一个numpy数组(大概是短整数,每个 2 个字节,因为您可能需要超过 256 个不同的值)——对于 <200 万个单元格,这将花费不到 4MB。

如果由于某种原因我无法承受 numpy 依赖(例如在不支持 numpy 的 App Engine 上),我会使用标准库数组模块——它只支持一维数组,但它就像空间一样——对于大型同构数组,与 numpy 一样有效,并且您提到的 getter/setter 例程可以完美地“线性化”一个 3 项元组,它是您将自然索引转换为一维数组的单个整数索引。

一般来说,只要您有大型的同构、密集的向量或数字矩阵,就考虑 numpy(或数组)——Python 内置列表在这个用例中非常浪费空间(由于它们的通用性,您没有使用和这里不需要!-),节省内存也间接转化为节省时间(更好的缓存,更少的间接级别等)。