数组分配问题
在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, ...
所以你看, a
和b
实际上是指内存中的同一位置,即同一个对象。 对其中一个的更改会反映在另一个上,因为它们只是两个同名的名字。
如果你想实际制作一个数组的副本,你必须调用一个方法来明确地做到这一点。 Numpy数组有一个copy
方法,你可以使用这个目的。 所以,如果你写
b = a.copy()
那么Python将首先创build一个数组的副本 – 也就是说,它留出一个新的内存区域,比如在地址0x123904381,然后到内存地址0x123674283,并从内存的后一部分复制数组的所有值前者。 所以你有相同的内容坐在记忆中的两个不同的地方。
..., 'a' : 0x123674283, ..., 'b' : 0x123904381, ...
现在,当你改变b
一个元素时,这个改变就不会出现在a
,因为a
和b
不再引用计算机内存的同一部分。 由于arrays数据有两个独立的副本,因此可以更改一个,而不会影响另一个。
简而言之,variables赋值会创build对现有对象的新引用。
A = object # A points to object in memory B = A # B points to the same object