数组分配问题

在Python 2.6.5与Numpy有一个奇怪的问题。 我分配一个numpy数组,然后等同于一个新的variables。 当我对新arrays执行任何操作时,原始值也会改变。 这是为什么? 请看下面的例子。 请赐教,因为我对Python相当陌生,而且一般编程。

-Sujan

>>> import numpy as np >>> a = np.array([[1,2],[3,4]]) >>> b = a >>> b array([[1, 2], [3, 4]]) >>> c = a >>> c array([[1, 2], [3, 4]]) >>> c[:,1] = c[:,1] + 5 >>> c array([[1, 7], [3, 9]]) >>> b array([[1, 7], [3, 9]]) >>> a array([[1, 7], [3, 9]]) 

这实际上不是一个问题; 这是数组(和其他对象)在Python中工作的方式。

想想这样:你在你的代码示例中创build的数组是一个对象,位于内存中的某个位置。 但是你不能在你的程序中通过告诉Python在内存中的哪个地方去寻找它, 你必须给它一个名字。 当你写

 a = np.array([[1,2],[3,4]]) 

你正在创build数组并创build一个名字, a引用它的名字。 从这一点上,Python知道a指的是“内存地址0x123674283”(或其他)。 Python运行时有一个内部表(如果我没有记错的话,称为“符号表”)包含所有这些信息,所以在上面这行Python代码运行之后,这个表将包含

 ..., 'a' : 0x123674283, ... 

当你将一个variables的值赋给另一个时,比如

 b = a 

Python不复制整个数组,因为如果它是一个大数组,它将需要很长时间。 相反,它进入符号表并将a的内存地址复制到b表中的新行。 所以你结束了

 ..., 'a' : 0x123674283, ..., 'b' : 0x123674283, ... 

所以你看, ab实际上是指内存中的同一位置,即同一个对象。 对其中一个的更改会反映在另一个上,因为它们只是两个同名的名字。

如果你想实际制作一个数组的副本,你必须调用一个方法来明确地做到这一点。 Numpy数组有一个copy方法,你可以使用这个目的。 所以,如果你写

 b = a.copy() 

那么Python将首先创build一个数组的副本 – 也就是说,它留出一个新的内存区域,比如在地址0x123904381​​,然后到内存地址0x123674283,并从内存的后一部分复制数组的所有值前者。 所以你有相同的内容坐在记忆中的两个不同的地方。

 ..., 'a' : 0x123674283, ..., 'b' : 0x123904381, ... 

现在,当你改变b一个元素时,这个改变就不会出现在a ,因为ab不再引用计算机内存的同一部分。 由于arrays数据有两个独立的副本,因此可以更改一个,而不会影响另一个。

简而言之,variables赋值会创build对现有对象的新引用。

  A = object # A points to object in memory B = A # B points to the same object