我可以通过以下方式构造稀疏矩阵(例如csr):
row = np.array([0, 0, 1, 2, 2, 2])
col = np.array([0, 2, 2, 0, 1, 2])
data = np.array([1, 2, 3, 4, 5, 6])
csr_matrix((data, (row, col)), shape=(3, 3))
考虑到我的输入数据,这将是最简单,最自然的方式。
现在,data
可能会发生变化,而结构信息row
和col
保持不变。
如何在不重复整个构建过程的情况下有效设置新data
?
(我希望我必须以某种方式从data
获取一个线性索引图到内部矩阵存储中,但我不知道是否提供了它。)
答案 0 :(得分:0)
您可以分配到.data
-
sparse_matrix.data = new_data[np.lexsort([col, row])]
示例运行 -
In [109]: row = np.array([2, 0, 0, 1, 2, 2])
...: col = np.array([2, 0, 2, 2, 0, 1])
...: data = np.array([1, 2, 3, 4, 5, 6])
...: mat1 = csr_matrix((data, (row, col)), shape=(3, 3))
...:
In [110]: mat1.toarray()
Out[110]:
array([[2, 0, 3],
[0, 0, 4],
[5, 6, 1]])
In [111]: new_data = np.array([23,90,45,67,21,99])
In [112]: mat1.data = new_data[np.lexsort([col, row])]
In [113]: mat1.toarray()
Out[113]:
array([[90, 0, 45],
[ 0, 0, 67],
[21, 99, 23]])
如果效果更好,我们可以将np.lexsort([col, row])
替换为np.ravel_multi_index((row, col), mat1.shape).argsort()
。
答案 1 :(得分:0)
通常以这种方式制作稀疏coo
矩阵时,其属性只是输入数组。
In [241]: Mo = sparse.coo_matrix((data, (row, col)), shape=(3,3))
In [242]: Mo.data
Out[242]: array([1, 2, 3, 4, 5, 6])
In [243]: Mo.row
Out[243]: array([0, 0, 1, 2, 2, 2])
In [244]: Mo.col
Out[244]: array([0, 2, 2, 0, 1, 2])
In [245]: id(Mo.col), id(col) # ids match
Out[245]: (2851595992, 2851595992)
转换为csr
(或调用csr_matrix
)时,所有三个都会被转换。这是在编译的代码中完成的。将重复的坐标相加(如记录的那样)。另请注意新的dtypes:
In [246]: Mr = Mo.tocsr()
In [247]: Mr.data
Out[247]: array([1, 2, 3, 4, 5, 6], dtype=int32)
In [248]: Mr.indices
Out[248]: array([0, 2, 2, 0, 1, 2], dtype=int32)
In [249]: Mr.indptr
Out[249]: array([0, 2, 3, 6], dtype=int32)
coo
值可以按任何顺序排列; csr
个已排序。在您的示例中,这并未更改顺序(indptr
使用精简形式替换row
。)
您可以使用以下方式检查csr
格式:
In [266]: Mr.has_canonical_format
Out[266]: True
In [267]: Mr.has_sorted_indices
Out[267]: True
如果这些不是真的,则可以使用Mr.sort_indices
恢复它们。
我不知道哪些操作会扰乱订单。我非常确定您使用的构造会产生规范矩阵。
我注意到Mr.copy
使用
def _with_data(self,data,copy=True):
"""Returns a matrix with the same sparsity structure as self,
but with different data. By default the structure arrays
(i.e. .indptr and .indices) are copied.
"""
if copy:
return self.__class__((data,self.indices.copy(),self.indptr.copy()),
shape=self.shape,dtype=data.dtype)
else:
return self.__class__((data,self.indices,self.indptr),
shape=self.shape,dtype=data.dtype)
我不会付出太多努力来避免复制和新的矩阵。错误的是安全而不是速度。请注意,sparse
会一直制作新的矩阵,例如在执行Mr[1,:]
时或在进行数学运算时。对于某些重复操作,可能值得花时间在“就地”做事,但不要经常尝试这样做。
您可能还会发现sparse.bmat
的代码具有指导性。它从较小的矩阵构建一个新的矩阵。请注意它如何将coo
属性组合成一个新的大集。
lil
也是面向行的:
In [256]: Ml = Mo.tolil()
In [257]: Ml.data
Out[257]: array([[1, 2], [3], [4, 5, 6]], dtype=object)
In [258]: Ml.rows
Out[258]: array([[0, 2], [2], [0, 1, 2]], dtype=object)