<p>正如我在接受的答案中所评论的那样,<code>data</code>是“参差不齐”的,不能组成数组</p>
<p>现在,如果数据具有更规则的形式,则无循环解决方案是可能的。但是转换成这种形式需要同样的双循环</p>
<pre><code>In [814]: [(i,j,v) for i,row in enumerate(data) for j,v in row]
Out[814]:
[(0, 0, 0.5),
(0, 1, 0.6),
(1, 4, 0.01),
(1, 5, 0.005),
(1, 6, 0.002),
(2, 1, 0.7)]
</code></pre>
<p>“转置”并分为3个变量:</p>
<pre><code>In [815]: I,J,V=zip(*_)
In [816]: I,J,V
Out[816]: ((0, 0, 1, 1, 1, 2), (0, 1, 4, 5, 6, 1), (0.5, 0.6, 0.01, 0.005, 0.002, 0.7))
</code></pre>
<p>我在这里坚持使用列表转置,以便不将整数索引转换为浮点。它也可能更快,因为从列表中生成数组并不是一项简单的任务</p>
<p>现在我们可以通过<code>numpy</code>魔术来赋值:</p>
<pre><code>In [819]: arr = np.zeros((3,7))
In [820]: arr[I,J]=V
In [821]: arr
Out[821]:
array([[0.5 , 0.6 , 0. , 0. , 0. , 0. , 0. ],
[0. , 0. , 0. , 0. , 0.01 , 0.005, 0.002],
[0. , 0.7 , 0. , 0. , 0. , 0. , 0. ]])
</code></pre>
<p><code>I,J,V</code>也可以用作<code>scipy.sparse.coo_matrix</code>调用的输入,生成稀疏矩阵</p>
<p>说到稀疏矩阵,这里是稀疏版本的<code>arr</code>的样子:</p>
<p>在列表格式中:</p>
<pre><code>In [822]: from scipy import sparse
In [823]: M = sparse.lil_matrix(arr)
In [824]: M
Out[824]:
<3x7 sparse matrix of type '<class 'numpy.float64'>'
with 6 stored elements in List of Lists format>
In [825]: M.A
Out[825]:
array([[0.5 , 0.6 , 0. , 0. , 0. , 0. , 0. ],
[0. , 0. , 0. , 0. , 0.01 , 0.005, 0.002],
[0. , 0.7 , 0. , 0. , 0. , 0. , 0. ]])
In [826]: M.rows
Out[826]: array([list([0, 1]), list([4, 5, 6]), list([1])], dtype=object)
In [827]: M.data
Out[827]:
array([list([0.5, 0.6]), list([0.01, 0.005, 0.002]), list([0.7])],
dtype=object)
</code></pre>
<p>以及更常见的<code>coo</code>格式:</p>
<pre><code>In [828]: Mc=M.tocoo()
In [829]: Mc.row
Out[829]: array([0, 0, 1, 1, 1, 2], dtype=int32)
In [830]: Mc.col
Out[830]: array([0, 1, 4, 5, 6, 1], dtype=int32)
In [831]: Mc.data
Out[831]: array([0.5 , 0.6 , 0.01 , 0.005, 0.002, 0.7 ])
</code></pre>
<p>以及大多数计算中使用的csr:</p>
<pre><code>In [832]: Mr=M.tocsr()
In [833]: Mr.data
Out[833]: array([0.5 , 0.6 , 0.01 , 0.005, 0.002, 0.7 ])
In [834]: Mr.indices
Out[834]: array([0, 1, 4, 5, 6, 1], dtype=int32)
In [835]: Mr.indptr
Out[835]: array([0, 2, 5, 6], dtype=int32)
</code></pre>