python: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]

如果我将一个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]                                                                                                                                                                                                                   
      [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
  • 这里没有意外
  • 这只是(2)次刷新,但请注意,
    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赋值给
    子矩阵的整个第一行。