Python—像素和关联值的高效表示

Python—像素和关联值的高效表示,python,data-structures,matrix,numpy,sparse-matrix,Python,Data Structures,Matrix,Numpy,Sparse Matrix,我使用python处理大型ish(大约2000 x 2000)矩阵,其中矩阵中的每个I,J点表示一个像素 矩阵本身是稀疏的(即其中很大一部分将具有零值),但当它们被更新时,它们往往是对矩形“块”中大量相邻像素的增量操作,而不是在这里或那里随机像素(我目前不使用该属性)。 我对矩阵运算有点陌生,但我已经研究了许多可能的解决方案,包括各种风格的scipy稀疏矩阵。到目前为止,坐标(COO)矩阵似乎是最有希望的。 例如,当我想增加一个块形状时,我必须沿着以下几行做一些事情: >>>

我使用python处理大型ish(大约2000 x 2000)矩阵,其中矩阵中的每个
I
J
点表示一个像素

矩阵本身是稀疏的(即其中很大一部分将具有零值),但当它们被更新时,它们往往是对矩形“块”中大量相邻像素的增量操作,而不是在这里或那里随机像素(我目前不使用该属性)。 我对矩阵运算有点陌生,但我已经研究了许多可能的解决方案,包括各种风格的
scipy
稀疏矩阵。到目前为止,坐标(COO)矩阵似乎是最有希望的。 例如,当我想增加一个块形状时,我必须沿着以下几行做一些事情:

>>> from scipy import sparse
>>> from numpy import array
>>> I = array([0,0,0,0])
>>> J = array([0,1,2,3])
>>> V = array([1,1,1,1])
>>> incr_matrix = sparse.coo_matrix((V,(I,J)),shape=(100,100))
>>> main_matrix += incr_matrix  #where main_matrix was previously defined
在未来,我希望在任何情况下都有更丰富的像素值表示(元组表示RGB等),numpy array不支持开箱即用(或者我需要使用)


最终,我将有许多这样的矩阵,我需要对它们进行简单的算术运算,并且我需要代码尽可能高效——并且是可分发的,因此我需要能够以一个小的表示形式持久化和交换这些对象,而不必付出太大的代价。我想知道这是不是正确的方法,还是我应该用<代码> DISTS <代码>等来滚动我自己的结构?四叉树结构在存储稀疏数据方面非常有效,并且还有一个额外的优势,即如果您使用由大量相似数据块组成的结构,则表示可以非常紧凑。我不确定这是否特别适用于您正在做的事情,因为我不知道“分块工作”是什么意思,但作为一种替代的稀疏矩阵实现,它确实值得一试。

我会说,是的,这是一种方法。肯定是过度使用字典了!构建“向量”数组时,请使用结构化数组,即定义自己的数据类型:

rgbtype = [('r','uint8'),('g','uint8'),('b','uint8')]
当增加块时,它将如下所示:

main_matrix['r'][blk_slice] += incr_matrix['r']
main_matrix['g'][blk_slice] += incr_matrix['g']
main_matrix['b'][blk_slice] += incr_matrix['b']
更新:


看起来你不能用coo_矩阵进行矩阵运算,它们只是作为一种方便的方式来填充稀疏矩阵。在进行更新之前,必须将它们转换为另一种(稀疏)矩阵类型

一般规则是,首先让代码工作,然后根据需要进行优化

在这种情况下,请使用普通numpy 2000x2000阵列,或对RGB使用2000x2000x3阵列。这将是更容易和更快的工作,只是一个小的内存需求,并有许多其他优势,例如,您可以使用标准的图像处理工具,等等

然后,如果需要“保存和交换这些对象”,您可以使用gzip、pytables、jpeg或其他方式压缩它们,但无需限制基于数据操作的存储需求


通过这种方式,您可以同时获得更快的处理速度和更好的压缩性能。我怀疑您是否能够提供比scipy和numpy更好的功能。但我在这方面还不够熟练,不能更加肯定。顺便说一下,我不喜欢使用“向量”这个词。一方面,Python中没有名为“vector”的内置数据结构。另一方面,二维表不太可能在数学意义上被称为“向量”。因此,您的实体既不是一个名为“vector”的Python对象,也不是一个名为“vector”的数学结构,这是正确的-它确实应该说矩阵而不是向量(?):2000x2000根本不是很大。没有必要使用稀疏数组。仅使用普通numpy阵列应该可以获得更好的性能。顺便说一句,numpy非常支持每个像素的“类似于“RGB”的向量”。。。它只是一个2000x2000x3阵列!它工作得很好,而且效率很高!我同意乔的看法。索引每个更新可能比最终存储阵列时压缩阵列更昂贵。或者只使用mxnx3阵列。特别是对于图像数据,
mxnxnumbands
数组比结构化数组更能处理问题,因为它可以让您更容易地分离带(
x[…,1]
而不是
x['r']。重塑(m,n)
)。使用结构化数组肯定没有什么错,我个人认为简单的3D数组更适合图像数据。不管怎样,+1来自我。我不确定你是否/如何使用稀疏矩阵。对不起,我在发表评论时忘了我们在谈论稀疏矩阵。。。稀疏矩阵本质上是二维的,所以不能。在这种情况下,结构化稀疏阵列无疑是一种可行的方法。我仍然认为,如果他要增加几个块,最好避免使用稀疏矩阵,但这是一个完全不同的问题…@joe,你为什么不建议使用稀疏矩阵?对标准矩阵进行酸洗会导致非常大的中间内存需求(每个矩阵约140MB),这就是我试图通过使用稀疏矩阵来优化的内容。@flyingcrab-稀疏矩阵上的算术运算将比密集阵列上的运算慢得多,除非矩阵非常稀疏。(此外,只有
lil_matrix
支持您想要的索引类型,它们的缺点之一是运算速度慢)。如果您担心中间内存需求,请不要
pickle
matrix!使用
numpy.save(…)
。酸洗确实需要大量中间内存,这就是存在
numpy.save
numpy.savez
的原因。总的来说,我只是认为稀疏矩阵是你问题的错误答案。。。希望有帮助!该代码确实使用标准数组,但是2000 x 2000