我想用scipy.sparse.dia_matrix记住一个五对角正方形矩阵。第一个和最后一个对角线距离主要对角线较远,因此它们包含的元素少于主要对角线。似乎dia_matrix仅接受与主对角线长度相同的对角线。我想节省内存,并给它不同长度的数组。可能吗?下面是一个示例(三对角线):
diag1 = [88,99]
main_diag = [1,2,3,4]
diag2 = [ 101,202]
A = [ 1, 0, 88, 0
0, 2, 0, 99
101, 0, 3, 0
0, 202, 0, 4 ]
A = scipy.sparse.dia_matrix(([[diag1],[main_diag],[diag2]],offsets), shape= (4,4))
但是它给了我一个错误,除非我不将对角线记为:
diag1 = [0,0,88,99]
main_diag = [1,2,3,4]
diag2 = [ 101,202,0,0]
但是这种方式不能节省内存。
答案 0 :(得分:0)
您的稠密矩阵(为什么不兼容此cut-n-paste?)
In [589]: A = np.array([[ 1, 0, 88, 0],
...: [0, 2, 0, 99],
...: [101, 0, 3, 0],
...: [0, 202, 0, 4] ])
...:
In [590]: A
Out[590]:
array([[ 1, 0, 88, 0],
[ 0, 2, 0, 99],
[101, 0, 3, 0],
[ 0, 202, 0, 4]])
我们可以直接从dia
制作A
矩阵:
In [591]: M = sparse.dia_matrix(A)
In [592]: M
Out[592]:
<4x4 sparse matrix of type '<class 'numpy.int64'>'
with 8 stored elements (3 diagonals) in DIAgonal format>
dia
格式存储的是两个数组中的值,分别是2d data
和1d offsets
:
In [593]: M.data
Out[593]:
array([[101, 202, 0, 0],
[ 1, 2, 3, 4],
[ 0, 0, 88, 99]])
In [594]: M.offsets
Out[594]: array([-2, 0, 2], dtype=int32)
我们可以使用sparse.diags
函数从您的3个对角线构造dia
矩阵:
In [605]: M1 = sparse.diags([diag1, main_diag, diag2],[2,0,-2], dtype=int)
In [606]: M1
Out[606]:
<4x4 sparse matrix of type '<class 'numpy.int64'>'
with 8 stored elements (3 diagonals) in DIAgonal format>
In [607]: M1.A
Out[607]:
array([[ 1, 0, 88, 0],
[ 0, 2, 0, 99],
[101, 0, 3, 0],
[ 0, 202, 0, 4]])
In [608]: M1.data
Out[608]:
array([[ 0, 0, 88, 99],
[ 1, 2, 3, 4],
[101, 202, 0, 0]])
但是底层存储是相同的。
我不知道dia_matrix
为什么使用这种格式的详细信息。我怀疑这与存储和处理成本的平衡有关。要将data
存储为2d数组,它必须具有某种填充。否则,您将使用[diag1, main_diag, diag2]
中的列表列表(或数组/列表的对象数组)。是否使用更多或更少的内存可能取决于矩阵的大小以及offsets
的距离。
以lil
格式,同一矩阵存储为2个列表数组:
In [611]: M.tolil().data
Out[611]:
array([list([1, 88]), list([2, 99]), list([101, 3]), list([202, 4])],
dtype=object)
In [612]: M.tolil().rows
Out[612]:
array([list([0, 2]), list([1, 3]), list([0, 2]), list([1, 3])],
dtype=object)
和coo
中的
In [615]: M.tocoo().data
Out[615]: array([101, 202, 1, 2, 3, 4, 88, 99])
In [616]: M.tocoo().row
Out[616]: array([2, 3, 0, 1, 2, 3, 0, 1], dtype=int32)
In [617]: M.tocoo().col
Out[617]: array([0, 1, 0, 1, 2, 3, 2, 3], dtype=int32)
csr
被广泛用于计算,它压缩row
数组。
如果您以密集形式进行所有计算,则可能需要根据以下内容构造A
:
np.diag(main_diag,0)+np.diag(diag1,2)+np.diag(diag2,-2)
将此与sparse
中介方法进行比较:
In [623]: timeit np.diag(main_diag,0)+np.diag(diag1,2)+np.diag(diag2,-2)
27.5 µs ± 1.28 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [624]: timeit sparse.diags([diag1, main_diag, diag2],[2,0,-2], dtype=int).A
288 µs ± 13 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)