有没有简单的方法在python中稀疏地存储具有冗余模式的矩阵?

时间:2013-03-22 22:03:54

标签: python matrix python-2.7 numpy sparse-matrix

我正在处理的矩阵类型是从一个向量创建的,如下所示:

从长度为L的1-d向量V开始。

要从具有N行的V创建矩阵A,从V的第i个条目开始,将A的第i列设为V的前N个条目,只要在V中剩余足够的条目即可填写专栏。这意味着A有L - N + 1列。

以下是一个例子:

V = [0, 1, 2, 3, 4, 5]
N = 3

A =
[0 1 2 3
 1 2 3 4
 2 3 4 5]

以这种方式表示矩阵需要比我的机器更多的内存。有没有合理的方法来稀疏地存储这个矩阵?我正在存储N *(L - N + 1)值,当我只需要存储L值时。

2 个答案:

答案 0 :(得分:3)

您可以按如下方式查看原始矢量:

>>> import numpy as np
>>> from numpy.lib.stride_tricks import as_strided
>>> 
>>> v = np.array([0, 1, 2, 3, 4, 5])
>>> n = 3
>>> 
>>> a = as_strided(v, shape=(n, len(v)-n+1), strides=v.strides*2)
>>> a
array([[0, 1, 2, 3],
       [1, 2, 3, 4],
       [2, 3, 4, 5]])

这是一个视图,而不是原始数据的副本,例如

>>> v[3] = 0
>>> v
array([0, 1, 2, 0, 4, 5])
>>> a
array([[0, 1, 2, 0],
       [1, 2, 0, 4],
       [2, 0, 4, 5]])

但是你必须小心不要在触发副本的a上进行任何操作,因为这样可以通过天花板发送你的记忆。

答案 1 :(得分:1)

如果您已经在使用numpy,请使用其跨步或稀疏数组,正如Jaime所解释的那样。

如果你 已经使用numpy,你可能会强烈考虑使用它。

如果你需要坚持使用纯Python,有三种明显的方法可以做到这一点,具体取决于你的用例。

对于跨步或稀疏但集群的数组,您可以有效地执行与numpy相同的操作。

或者您可以使用简单的运行长度编码方案,也可以使用更高级别的运行列表,或者指向每个第N个元素的指针列表,甚至是整个堆栈的列表(每100个元素一个) ,每10000个一个等。)。

但是对于大多数一致密集的数组,最简单的方法是简单地将dictdefaultdict映射索引存储到值。随机访问查找或更新仍然是O(1) - 尽管具有更高的常数因子 - 并且您浪费存储(实际上)散列,密钥和值而不仅仅是每个非默认元素的值的存储更多而不是存储默认元素的值,只要你的密度小于0.33就可以了。