这实际上完全不是问题,这是Python中数组(和其他对象)的工作方式。
可以这样考虑:你在代码示例中创建的数组是一个对象,它位于内存中的某个位置。但是你不能通过告诉Python在内存中哪里查找它来在程序中使用它,你必须给它一个名称。当你写下
a = np.array([[1,2],[3,4]])
你既创建了数组,又创建了一个名字 a
来引用它。从那时起,Python 就知道 a
指向"内存地址0x123674283"(或其他地址)。在 Python 运行时有一个内部表格(如果我没记错的话称为 "符号表"),其中包含所有这些信息,因此在上述 Python 代码运行后,该表格将包含:
...,
'a' : 0x123674283,
...
当你将一个变量的值赋给另一个变量时,如下所示:
b = a
Python并没有复制整个数组,因为如果数组很大的话,会花费很长时间。相反,它会去符号表中将 a
的内存地址复制到 b
表的一个新行中。这样你最终得到的是:
...,
'a' : 0x123674283,
...,
'b' : 0x123674283,
...
因此,你可以看到,a
和b
实际上是指向内存中相同的位置,也就是同一个对象。由于它们只是同一物体的两个名称,任何对其一个的更改都会反映在另一个上。
如果你想真正地复制数组,你必须显式调用一个方法来完成这个任务。Numpy数组有一个copy
方法,你可以用它来实现这个目的。所以,如果你写:
b = a.copy()
那么Python首先会实际复制该数组 - 也就是说,它会设置一个新的内存区域,比如在地址0x123904381处,然后从内存地址0x123674283处复制数组的所有值到前面的内存中。因此,您拥有相同的内容同时存在于内存的两个不同位置。
...,
'a' : 0x123674283,
...,
'b' : 0x123904381,
...
现在,当您更改b
中的一个元素时,该更改不会显示在a
中,因为a
和b
不再引用计算机内存的同一部分。由于数组数据有两个独立的副本,您可以更改一个而不影响另一个。