首页 > 解决方案 > 在 Python 和 Scipy.sparse 中,如何通过循环将矩阵的值分配给另一个较大矩阵的块?

问题描述

这适用于 Python 3.x 或更具体地说是 Scipy.sparse。我想写

import numpy as np, scipy.sparse as sp

A = sp.csc_matrix((4,3))
B = sp.csc_matrix(np.random.rand(2,1))
A[2:-1,0] = B

最后一行不起作用。我打算最后一行将矩阵 B 插入 A 作为第 3 行到第 4 行和第 0 列的块。在没有循环的情况下实现此分配的正确方法是什么?

标签: python-3.xscipysparse-matrix

解决方案


设置

In [219]: from scipy import sparse                                                                     
In [220]: A = sparse.csr_matrix((4,3))                                                                 
In [221]: A                                                                                            
Out[221]: 
<4x3 sparse matrix of type '<class 'numpy.float64'>'
    with 0 stored elements in Compressed Sparse Row format>
In [222]: B = sparse.csr_matrix(np.random.rand(2,1))                                                   
In [223]: B                                                                                            
Out[223]: 
<2x1 sparse matrix of type '<class 'numpy.float64'>'
    with 2 stored elements in Compressed Sparse Row format>
In [224]: B.A                                                                                          
Out[224]: 
array([[0.04427272],
       [0.03421125]])

您的尝试,出现错误

In [225]: A[2:-1, 0] = B                                                                               
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-225-0dcce4b72635> in <module>
----> 1 A[2:-1, 0] = B

/usr/local/lib/python3.6/dist-packages/scipy/sparse/_index.py in __setitem__(self, key, x)
    111             if not ((broadcast_row or x.shape[0] == i.shape[0]) and
    112                     (broadcast_col or x.shape[1] == i.shape[1])):
--> 113                 raise ValueError('shape mismatch in assignment')
    114             if x.size == 0:
    115                 return

ValueError: shape mismatch in assignment

所以让我们专注于形状:

In [226]: A[2:-1, 0].shape                                                                             
Out[226]: (1, 1)
In [227]: B.shape                                                                                      
Out[227]: (2, 1)

嗯嗯!即使使用密集数组,我们也不能将 (2,1) 放入 (1,1) 槽中。

如果我们去掉 -1,我们会得到一个 2 元素插槽:

In [230]: A.A[2:,0].shape                                                                              
Out[230]: (2,)

现在任务有效 - 带有警告。

In [231]: A[2:, 0] = B                                                                                 
/usr/local/lib/python3.6/dist-packages/scipy/sparse/_index.py:118: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
  self._set_arrayXarray_sparse(i, j, x)
In [232]: A                                                                                            
Out[232]: 
<4x3 sparse matrix of type '<class 'numpy.float64'>'
    with 2 stored elements in Compressed Sparse Row format>
In [233]: A.A                                                                                          
Out[233]: 
array([[0.        , 0.        , 0.        ],
       [0.        , 0.        , 0.        ],
       [0.04427272, 0.        , 0.        ],
       [0.03421125, 0.        , 0.        ]])

作为一般规则,我们不会通过将值分配给现有的“空”矩阵来制作稀疏矩阵。我们csr用输入的样式制作一个矩阵coo——行、列、数据数组。


推荐阅读