Python - 像素及其值的高效表示方法
我正在用Python处理一些比较大的矩阵(大约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数组中是默认不支持的(或者我可能需要使用 这个)。
最终,我会有很多这样的矩阵需要进行简单的算术运算,我希望代码尽可能高效,并且能够分发,所以我需要能够以较小的方式保存和交换这些对象,而不会有太大的损失。我在想这样做是否正确,还是应该考虑用 dicts
等自己构建一些结构?
3 个回答
你可以考虑看看四叉树这种实现方式。四叉树这种结构在存储稀疏数据时非常高效,而且如果你处理的是由很多相似数据块组成的结构,它的表示方式可以非常紧凑。我不太确定这是否适合你所做的事情,因为我不太明白你说的“以块为单位工作”是什么意思,但作为一种稀疏矩阵的替代实现,确实值得一试。
我觉得,没错,这确实是个好方法。绝对比用字典来构建东西要好!当你在创建一个“向量”或数组时,应该使用结构化数组,也就是定义你自己的数据类型:
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_matrix进行矩阵运算,它只是一个方便的方式来填充稀疏矩阵。在进行更新之前,你必须把它转换成另一种(稀疏)矩阵类型。文档
一般来说,先让代码能正常运行,再考虑优化,如果有必要的话...
在这个情况下,使用一个普通的numpy 2000x2000的数组,或者2000x2000x3的数组来处理RGB颜色。这种方式会更简单、更快速,内存占用也很小,还有很多其他好处,比如你可以使用标准的图像处理工具等等。
然后,如果需要“保存和交换这些对象”,你可以直接用gzip、pytables、jpeg等工具来压缩它们,但没必要限制你的数据处理方式来适应存储需求。
这样一来,你就能实现更快的处理速度和更好的压缩效果。