首页 > 解决方案 > 更改 scipy 稀疏矩阵的对角线或数据属性也会更改该矩阵的所有副本

问题描述

我有一个 scipy 稀疏矩阵variable,我将它复制到另一个新的variable. 如果我现在更改 new 中稀疏矩阵的对角线,variable则原始中的稀疏矩阵variable也会更新。如果我更改数据,也会发生同样的情况attribute。我不明白为什么会这样,这种行为是否有我看不到的目的,或者我是否以无意的方式做某事?

我想要的是我从一个稀疏矩阵开始,制作它的几个副本,并以足够的方式修改对角线或所有条目以用于这些副本。但我的修改正在影响所有副本。

power()我发现如果我使用创建稀疏矩阵副本的方法(例如使用 @ 或矩阵乘法),则不会出现问题。

我想要的一个修改是稀疏矩阵的副本,我在其中获取所有条目的绝对值。如果我abs()直接在稀疏矩阵上使用,它会根据需要创建一个副本,一切都很好。但是,如果我将所有条目的绝对值写入attribute稀疏矩阵的数据,它也会影响稀疏矩阵的所有其他副本。我发现后一种方法要快得多,这就是我更喜欢使用它的原因。

该问题与稀疏矩阵格式无关(除了 lil 或 dok 格式的数据属性)。

我在 Spyder 3.3.1 中使用Python 3.5.2and Python 3.7.3(两台不同的计算机)进行了尝试,我使用的是 scipy 版本 1.3.0。

假设我有一个稀疏矩阵

from scipy.sparse import csc_matrix as spmat
Msp = spmat(ar([[0.,-3.],[2.,-4.]]))

我做了一些副本(我也可以总是复制 Msp,没有什么区别)

M1 = Msp
M2 = M1

如果我现在这样做

M2.data = abs(M2.data)

或者

M1.setdiag([1,1])

它还会更改所有其他副本,例如在应用上述两个操作之后:

Msp.toarray()
array([[1., 3.],
       [2., 1.]])

M1 和 M2 也是如此。

我本来期望的

M2.toarray()
array([[ 0., 3.],
       [ 2., 4.]])

M1.toarray()
array([[1., -3.],
       [2., 1.]])

Msp.toarray()
array([[ 0., -3.],
       [ 2., -4.]])

另一方面,如果我做以下类型的事情

M2 = abs(M2)
M2 = M2.power(2)
M2 = M2@M2

它确实只影响 M2 并且像我预期的那样使 M1 和 Msp 保持不变。

标签: pythonscipysparse-matrix

解决方案


通过更改以下行:

M1 = Msp
M2 = M1

至:

M1 = Msp.copy()
M2 = M1.copy()

您给定的示例将按预期工作。

Numpy 数组是可变的,因此对对象的更改将影响引用该对象的所有变量。

换句话说:通过设置M2 = M1,M2 只是对 M1 的引用,因此如果 M1 被更改,它也会采用 M1 的值。M2 = M1.copy()另一方面,将 M1 的副本(“值”)传递给 M2,M2 此后独立于 M1 的更改。

最后给出的示例仅影响 M2 的原因是许多 numpy 函数返回的新数组独立于作为参数传递的数组。


推荐阅读