我有一个大的稀疏矩阵globalGrid(lil_matrix)和一个较小的矩阵localGrid(coo_matrix)。 localGrid表示globalGrid的一个子集,我想用localGrid更新globalGrid。为此,我使用以下代码(在Python Scipy中):
M=sparse.lil_matrix(2*np.ones([5,5]))
m = sparse.eye(3)
M.todense()
matrix([[ 2., 2., 2., 2., 2.],
[ 2., 2., 2., 2., 2.],
[ 2., 2., 2., 2., 2.],
[ 2., 2., 2., 2., 2.],
[ 2., 2., 2., 2., 2.]])
m.todense()
matrix([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])
其中xLocalGrid和yLocalGrid是localGrid原点相对于globalGrid的偏移量。
问题是localGrid是稀疏的,但零元素也分配给了globalGrid。有没有办法我只能分配存储的元素而不是0元素?
我发现numpy中的掩码数组,但这似乎不适用于稀疏的scipy矩阵。
编辑:在回答下面的评论时,这里有一个例子来说明我的意思:
首先设置矩阵:
M[1:4, 1:4] = m
然后分配:
M.todense()
matrix([[ 2., 2., 2., 2., 2.],
[ 2., 1., 0., 0., 2.],
[ 2., 0., 1., 0., 2.],
[ 2., 0., 0., 1., 2.],
[ 2., 2., 2., 2., 2.]])
现在的结果是:
matrix([[ 2., 2., 2., 2., 2.],
[ 2., 1., 2., 2., 2.],
[ 2., 2., 1., 2., 2.],
[ 2., 2., 2., 1., 2.],
[ 2., 2., 2., 2., 2.]])
我需要的结果是:
select * from mytable
order by
case
when `floor`+0 = 0 then 0
else 1
end , `floor`+0,`floor`
答案 0 :(得分:0)
该行
问题是localGrid是稀疏的,但是非零元素也分配给了globalGrid。有没有办法我只能分配存储的元素而不是0元素?
改为?
问题是localGrid是稀疏的,但零元素也分配给了globalGrid。有没有办法我只能分配存储的元素而不是0元素?
您的问题不是很清楚,但我猜测是因为globalGrid[a:b, c:d]
索引跨越了两个数组中应该为0的值,您担心0&是被复制。
让我们用真正的矩阵来试试。
In [13]: M=sparse.lil_matrix((10,10))
In [14]: m=sparse.eye(3)
In [15]: M[4:7,5:8]=m
In [16]: m
Out[16]:
<3x3 sparse matrix of type '<class 'numpy.float64'>'
with 3 stored elements (1 diagonals) in DIAgonal format>
In [17]: M
Out[17]:
<10x10 sparse matrix of type '<class 'numpy.float64'>'
with 3 stored elements in LInked List format>
In [18]: M.data
Out[18]: array([[], [], [], [], [1.0], [1.0], [1.0], [], [], []], dtype=object)
In [19]: M.rows
Out[19]: array([[], [], [], [], [5], [6], [7], [], [], []], dtype=object)
M
没有任何不必要的0。
如果稀疏矩阵中存在不必要的0,则csr
格式的往返应该照顾它们
M.tocsr().tolil()
csr
格式也有一个就地.eliminate_zeros()
方法。
所以你关注的是过度编写目标数组的非零值。
对于密集数组,使用nonzero
(或where
)可以解决这个问题:
In [87]: X=np.ones((10,10),int)*2
In [88]: y=np.eye(3)
In [89]: I,J=np.nonzero(y)
In [90]: X[I+3,J+2]=y[I,J]
In [91]: X
Out[91]:
array([[2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 1, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 1, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 1, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2]])
尝试稀疏等价物:
In [92]: M=sparse.lil_matrix(X)
In [93]: M
Out[93]:
<10x10 sparse matrix of type '<class 'numpy.int32'>'
with 100 stored elements in LInked List format>
In [94]: m=sparse.coo_matrix(y)
In [95]: m
Out[95]:
<3x3 sparse matrix of type '<class 'numpy.float64'>'
with 3 stored elements in COOrdinate format>
In [96]: I,J=np.nonzero(m)
In [97]: I
Out[97]: array([0, 1, 2], dtype=int32)
In [98]: J
Out[98]: array([0, 1, 2], dtype=int32)
In [99]: M[I+3,J+2]=m[I,J]
...
TypeError: 'coo_matrix' object is not subscriptable
我本可以使用稀疏矩阵自己的nonzero
。
In [106]: I,J=m.nonzero()
对于coo
格式,这与
In [109]: I,J=m.row, m.col
在这种情况下,我还可以使用data
属性:
In [100]: M[I+3,J+2]=m.data
In [101]: M.A
Out[101]:
array([[2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 1, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 1, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 1, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2]], dtype=int32)
m.nonzero
的代码可能具有指导意义
A = self.tocoo()
nz_mask = A.data != 0
return (A.row[nz_mask],A.col[nz_mask])
因此,您需要注意确保稀疏矩阵的索引和数据属性匹配。
还要注意哪些稀疏格式允许索引。 lil
有助于改变价值观。 csr
允许逐个元素索引,但如果您尝试将零值更改为非零(或v.v.),则会引发效率警告。 coo
有很好的索引和数据配对,但不允许索引。
另一个微妙的观点:在构建coo
时,您可以重复坐标。转换为csr
格式时,将这些值相加。但我建议的作业只会使用最后一个值,而不是总和。因此,请务必了解您的local
矩阵是如何构建的,并了解它是否是一个“干净”的矩阵。表示数据。
答案 1 :(得分:0)
我找到了一个有效的解决方案。而不是使用赋值,我循环遍历稀疏矩阵中的数据(使用M.data和M.rows)并逐个替换元素。
for idx, row in enumerate(m.rows):
for idy, col in enumerate(row):
M[yOffset+col, xOffset+idx] = m.data[idx][idy]
如果没有更简单/更快的方法来实现这个结果,我仍然很好奇。
我执行上述答案:
I,J = m.nonzero()
M[I+yOffset,J+xOffset] = m[I,J]
return M'
然而这稍微慢一些。