python - 更改 scipy 稀疏矩阵的对角线或数据属性也会更改该矩阵的所有副本
问题描述
我有一个 scipy 稀疏矩阵variable
,我将它复制到另一个新的variable
. 如果我现在更改 new 中稀疏矩阵的对角线,variable
则原始中的稀疏矩阵variable
也会更新。如果我更改数据,也会发生同样的情况attribute
。我不明白为什么会这样,这种行为是否有我看不到的目的,或者我是否以无意的方式做某事?
我想要的是我从一个稀疏矩阵开始,制作它的几个副本,并以足够的方式修改对角线或所有条目以用于这些副本。但我的修改正在影响所有副本。
power()
我发现如果我使用创建稀疏矩阵副本的方法(例如使用 @ 或矩阵乘法),则不会出现问题。
我想要的一个修改是稀疏矩阵的副本,我在其中获取所有条目的绝对值。如果我abs()
直接在稀疏矩阵上使用,它会根据需要创建一个副本,一切都很好。但是,如果我将所有条目的绝对值写入attribute
稀疏矩阵的数据,它也会影响稀疏矩阵的所有其他副本。我发现后一种方法要快得多,这就是我更喜欢使用它的原因。
该问题与稀疏矩阵格式无关(除了 lil 或 dok 格式的数据属性)。
我在 Spyder 3.3.1 中使用Python 3.5.2
and 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 保持不变。
解决方案
通过更改以下行:
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 函数返回的新数组独立于作为参数传递的数组。
推荐阅读
- jquery - 如何使元素在 Scroll 上淡出 - 我的代码在其他地方工作但不是在这里
- python - Newrelic + sqlalchemy
- php - Swiftmailer 和 Symfony Messenger 不能在 docker 中使用 AMQP 和 rabbitmq
- python - 在同一个文件中记录两个脚本
- python - 我应该在 PyQt 中重写我的 Tkinter,反之亦然?
- c++ - c++ 用近似值加速 Eigen 最小二乘求解器
- c# - System.Data.SqlClient.SqlException:“将 nvarchar 值转换为数据类型 int 时转换失败。”
- google-cloud-platform - 我可以告诉 Google Cloud SQL 将我的备份恢复到完全不同的数据库吗?
- sql - Redshift(在不同数据类型的两列之间复制数据
- python - 更改多个日期列的日期格式的功能