逻辑寻址numpy与其他矩阵混乱

时间:2013-10-10 15:46:43

标签: numpy matrix indexing addressing

我刚刚发现了一个问题而且我不知道它是否应该是这样的,或者我只是做错了。当我在numpy矩阵中使用逻辑寻址来改变矩阵的所有值时,比如等于1.所有其他矩阵都会以某种方式与此矩阵有关。

In [1]: import numpy as np
In [2]: from numpy import matrix as mtx
In [3]: A=mtx(np.eye(6))
In [4]: A
Out[4]: 
matrix([[ 1.,  0.,  0.,  0.,  0.,  0.],
        [ 0.,  1.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  1.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  1.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  1.,  0.],
        [ 0.,  0.,  0.,  0.,  0.,  1.]])

In [5]: B=A

In [6]: C=B

In [7]: D=C

In [8]: A[A==1]=5

In [9]: A
Out[9]: 
matrix([[ 5.,  0.,  0.,  0.,  0.,  0.],
        [ 0.,  5.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  5.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  5.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  5.,  0.],
        [ 0.,  0.,  0.,  0.,  0.,  5.]])

In [10]: B
Out[10]: 
matrix([[ 5.,  0.,  0.,  0.,  0.,  0.],
        [ 0.,  5.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  5.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  5.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  5.,  0.],
        [ 0.,  0.,  0.,  0.,  0.,  5.]])

In [11]: C
Out[11]: 
matrix([[ 5.,  0.,  0.,  0.,  0.,  0.],
        [ 0.,  5.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  5.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  5.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  5.,  0.],
        [ 0.,  0.,  0.,  0.,  0.,  5.]])

In [12]: D
Out[12]: 
matrix([[ 5.,  0.,  0.,  0.,  0.,  0.],
        [ 0.,  5.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  5.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  5.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  5.,  0.],
        [ 0.,  0.,  0.,  0.,  0.,  5.]])

谁能告诉我我做错了什么?这是一个错误吗?

1 个答案:

答案 0 :(得分:3)

这不是错误。在python中说B=A意味着BA都指向同一个对象。你需要复制矩阵。

>>> import numpy as np
>>> from numpy import matrix as mtx
>>> A = mtx(np.eye(6))
>>> B = A.copy()
>>> C = A

#Check memory locations.
>>> id(A)
19608352
>>> id(C)
19608352    #Same object as A
>>> id(B)
19607992    #Different object then A

>>> A[A==1] = 5
>>> B   #B is a different object then A
matrix([[ 1.,  0.,  0.,  0.,  0.,  0.],
        [ 0.,  1.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  1.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  1.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  1.,  0.],
        [ 0.,  0.,  0.,  0.,  0.,  1.]])

>>> C   #C is the same object as A
matrix([[ 5.,  0.,  0.,  0.,  0.,  0.],
        [ 0.,  5.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  5.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  5.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  5.,  0.],
        [ 0.,  0.,  0.,  0.,  0.,  5.]])

使用python list可以看到同样的问题:

>>> A = [5,3]
>>> B = A
>>> B[0] = 10
>>> A
[10, 3]

请注意,这是不同的,然后返回一个numpy视图,如下所示:

>>> A = mtx(np.eye(6))
>>> B = A[0]  #B is a view and now points to the first row of A

>>> id(A)
28088720
>>> id(B)  #Different objects!
28087568  
#B still points to the memory location of A's first row, but through numpy trickery

>>> B
matrix([[ 1.,  0.,  0.,  0.,  0.,  0.]])
>>> B *= 5 #In place multiplication, updates B which is the same as A's first row
>>> A
matrix([[ 5.,  0.,  0.,  0.,  0.,  0.],
        [ 0.,  1.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  1.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  1.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  1.,  0.],
        [ 0.,  0.,  0.,  0.,  0.,  1.]])

当视图B指向A的第一行时,A会发生变化。现在让我们强制复制。

>>> B = B*10 #Assigns B*10 to a different chunk of memory
>>> A
matrix([[ 5.,  0.,  0.,  0.,  0.,  0.],
        [ 0.,  1.,  0.,  0.,  0.,  0.],
        [ 0.,  0.,  1.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  1.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  1.,  0.],
        [ 0.,  0.,  0.,  0.,  0.,  1.]])
>>> B
matrix([[ 50.,   0.,   0.,   0.,   0.,   0.]])