<p>您寻找的显示非常类似于<code>str</code>稀疏矩阵的<code>coo</code>显示</p>
<pre><code>In [216]: M = (sparse.random(5,5,.2)*10).astype(int)
In [217]: M
Out[217]:
<5x5 sparse matrix of type '<class 'numpy.int64'>'
with 5 stored elements in COOrdinate format>
In [218]: print(M) # str(M)
(0, 0) 0
(0, 2) 8
(1, 3) 8
(1, 4) 8
(4, 4) 4
</code></pre>
<p>稀疏矩阵有一种<code>nonzero</code>方法来显示非零元素的坐标</p>
<pre><code>In [219]: M.nonzero()
Out[219]: (array([0, 1, 1, 4], dtype=int32), array([2, 3, 4, 4], dtype=int32))
</code></pre>
<p>对于<code>coo</code>,值存储为3个数组:</p>
<pre><code>In [220]: M.data, M.row, M.col
Out[220]:
(array([0, 8, 8, 8, 4]),
array([0, 0, 1, 1, 4], dtype=int32),
array([0, 2, 3, 4, 4], dtype=int32))
</code></pre>
<p>这些元素在<code>coo</code>格式中的顺序没有限制。甚至可能存在重复项,尽管这些项在转换为显示或<code>csr</code>格式时被求和</p>
<p>当我们将其转换为<code>lil</code>格式时,数据现在存储在两个列表数组中,每行一个列表:</p>
<pre><code>In [221]: Ml = M.tolil()
In [222]: Ml.data
Out[222]:
array([list([0, 8]), list([8, 8]), list([]), list([]), list([4])],
dtype=object)
In [223]: Ml.rows
Out[223]:
array([list([0, 2]), list([3, 4]), list([]), list([]), list([4])],
dtype=object)
</code></pre>
<p>它也有<code>nonzero</code>,但看看代码(它使用<code>coo</code>格式):</p>
<pre><code>In [224]: Ml.nonzero()
Out[224]: (array([0, 1, 1, 4], dtype=int32), array([2, 3, 4, 4], dtype=int32))
In [225]: Ml.nonzero??
Signature: Ml.nonzero()
Source:
def nonzero(self):
...
# convert to COOrdinate format
A = self.tocoo()
nz_mask = A.data != 0
return (A.row[nz_mask], A.col[nz_mask])
File: /usr/local/lib/python3.6/dist-packages/scipy/sparse/base.py
Type: method
</code></pre>
<p>实际上,这是所有稀疏格式的通用<code>nonzero</code>。<code>nz_mask</code>部分允许矩阵可能有0个尚未清理的值</p>
<p>虽然<code>lil</code>是为方便逐元素更新而设计的,但如果可能,我们通常建议从输入数组的<code>coo</code>样式创建一个矩阵。通常可以更有效地创建这些阵列。即使是列表附加或扩展也可以更快</p>
<p>进一步查看<code>Ml</code>矩阵上的迭代-它为每一行创建一个<code>lil</code>:</p>
<pre><code>In [230]: [x for x in Ml]
Out[230]:
[<1x5 sparse matrix of type '<class 'numpy.int64'>'
with 2 stored elements in List of Lists format>,
<1x5 sparse matrix of type '<class 'numpy.int64'>'
with 2 stored elements in List of Lists format>,
<1x5 sparse matrix of type '<class 'numpy.int64'>'
with 0 stored elements in List of Lists format>,
<1x5 sparse matrix of type '<class 'numpy.int64'>'
with 0 stored elements in List of Lists format>,
<1x5 sparse matrix of type '<class 'numpy.int64'>'
with 1 stored elements in List of Lists format>]
</code></pre>
<p>我们可以显示每行的数据:</p>
<pre><code>In [231]: [((i,x.rows[0]),x.data[0]) for i,x in enumerate(Ml)]
Out[231]:
[((0, [0, 2]), [0, 8]),
((1, [3, 4]), [8, 8]),
((2, []), []),
((3, []), []),
((4, [4]), [4])]
</code></pre>
<p>或者过滤掉空行:</p>
<pre><code>In [232]: [((i,x.rows[0]),x.data[0]) for i,x in enumerate(Ml) if x.data[0]]
Out[232]: [((0, [0, 2]), [0, 8]), ((1, [3, 4]), [8, 8]), ((4, [4]), [4])]
</code></pre>
<p>我们需要另一次迭代来分离每行中的元素</p>
<p>关于稀疏数组与密集数组的使用,一条经验法则是稀疏度(%非零元素)应该小于10%,这样才值得使用稀疏格式。但这在很大程度上取决于你的使用和关注</p>
<p>从简单的数据存储角度来看,请注意<code>coo</code>格式必须为每个非零项使用3个数字,而密集数组仅使用1个数字。稀疏矩阵乘法对于<code>csr</code>格式比较好。其他只关注<code>data</code>值(例如<code>sin</code>)的计算也相对有效。但是,如果数学必须比较两个矩阵的稀疏性,例如加法和元素乘法,稀疏性会更差</p>
<p>索引、切片和求和实际上可能使用矩阵乘法<code>coo</code>格式没有实现这些功能<code>lil</code>可以很好地执行一些面向行的操作。创建稀疏矩阵的基本动作需要时间</p>