python:numpy子矩阵何时按引用复制,何时按值复制?
如果我将一个numpy子矩阵指定给另一个,那么子矩阵似乎是作为引用插入到目标矩阵中的,而不是通过元素复制,有时不是,有时会发生奇怪的事情。结果让我有点吃惊,我试图理解确切的规则:python:numpy子矩阵何时按引用复制,何时按值复制?,python,numpy,matrix,reference,Python,Numpy,Matrix,Reference,如果我将一个numpy子矩阵指定给另一个,那么子矩阵似乎是作为引用插入到目标矩阵中的,而不是通过元素复制,有时不是,有时会发生奇怪的事情。结果让我有点吃惊,我试图理解确切的规则: import numpy as np x = np.matrix("1 2 3; 4 5 6; 7 8 9") print("0:" +str(x)) >>>0:[[1 2 3]
import numpy as np
x = np.matrix("1 2 3; 4 5 6; 7 8 9")
print("0:" +str(x))
>>>0:[[1 2 3]
[4 5 6]
[7 8 9]]
submatrix = np.zeros((2, 2), dtype=np.int)
submatrix[:,:] = x[:2, :2]
print("1:" + str(submatrix))
>>>1:[[1 2]
[4 5]]
x[0,0] = 0
print("2:" + str(submatrix))
>>>2:[[1 2] # since submatrix[0,0] didn't change to 0, elements must have been copied by value
[4 5]]
submatrix[:2,:2] = x[:2, :2] # perform same assignment again
x[0,0] = 1
print("3:" + str(submatrix))
>>>3:[[0 2] # eeeeh what? where is this 0 coming from??
[4 5]]
submatrix[0:2,1:2] = x[0:2, 2:3] # assign second column now
print("4:" + str(submatrix))
>>>4:[[0 3]
[4 6]] # assigned correctly
x[0,2] = -3
print("5:" + str(submatrix))
>>>5:[[0 3]
[4 6]] # no change
submatrix[0:1,0:2] = x[0:1, 2:3] # assigning first row
print("6:" + str(submatrix))
>>>6:[[-3 -3]
[ 4 6]] # dear lord!?
x[0,2] = -5
print("7:" + str(submatrix))
>>>7:[[-3 -3]
[ 4 6]] # no idea anymore
有人能解释一下发生了什么事吗
使用执行的代码
仔细检查,每次都会遇到完全相同的问题:在明确复制子矩阵之前,
x
中的更改不会反映在子矩阵中。对于您的测试:
x
中的更改不会自动转换为子矩阵中的更改。好的,现在我们有一个前提-数据被复制到子矩阵中,x
中的更改不会改变任何东西
#再次执行相同的任务
。嗯,不。也许是在使用的指数方面,但是x
已经发生了变化,因为你在(2)中所做的。该更改不是“隐式”(不确定是否有更好的术语)传递到子矩阵
,您正在使用子矩阵[:2,:2]=x[:2,:2]
积极传播更改。您已经在(2)中确定,之后的x[0,0]=1
赋值不会对子矩阵做任何事情,但它确实改变了x
x
在后台再次悄无声息地更改x
Out[70]:
matrix([[ 0, 2, -3],
[ 4, 5, 6],
[ 7, 8, 9]])
submatrix
Out[71]:
array([[0, 3],
[4, 6]])
子矩阵[0:1,0:2]
给出了数组([[0,3]])
。好的,有道理,你只是从最上面的一排中分一杯羹。它相当于子矩阵[0,:]
(第0行,此矩阵中的所有列),您现在可能会对切片表示法感到困惑,因为这是不必要的复杂。这在x[0:1,2:3]
中变得更加明显,它只是矩阵([[-3]])
;相当于x[0,2]
。这项任务的结果现在应该相当明显;将子矩阵的第一行设置为x[0,2]
处的标量值
我给你留7张。我认为您需要向自己澄清,因为我认为您开始在切片符号上打结 我不确定从参考/价值的角度考虑是否有帮助。我确信几年前有一个很好的问题,但我似乎找不到它。基本上,它归结为“它很复杂”,这就是为什么像这样的事情是一件事;即使是图书馆也不能保证没有详细的检查,也就是说,你的测试是不一致的;2和3是矛盾的。在2中,您确定数据已被复制,对
x
的更改不会反映在子矩阵中。然后在3中,您首先对数据进行一个新的拷贝,然后重新分配x
,并惊讶地看到您在第2点中所演示的内容。你把自己弄糊涂了;当然,赋值x[0,0]=1
不会产生错误difference@roganjosh公平-但为什么我的结果是2-3/6?我刚刚给了你一个逐步的答案:这里没有引用副本。在所有submatrix[…]=x[…]
分配中,x
的选定值被复制到submatrix
中的选定插槽中。每次作业前查看x
。“亲爱的上帝”赋值与子矩阵[0,:]=x[0,2]
相同,将-3赋值给子矩阵的整个第一行。