1

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

从长度为 L 的一维向量 V 开始。

要从 V 创建一个有 N 行的矩阵 A,只要 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]

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

4

2 回答 2

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触发副本进行任何操作,因为这会使您的内存使用量达到上限。

于 2013-03-22T22:08:10.460 回答
1

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

如果您还没有使用numpy,您可能会强烈考虑使用它。

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

对于跨步或稀疏但聚集的数组,您可以有效地执行与numpy.

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

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

于 2013-03-22T22:14:17.433 回答