Numpy数组分配问题

2024-05-16 05:11:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我在使用numpython2.6.5时遇到了一个奇怪的问题。我分配一个numpy数组,然后给它等同一个新变量。当我对新数组执行任何操作时,原始数组的值也会更改。为什么?请看下面的例子。请启发我,因为我对Python和一般编程还比较陌生。

-苏扬

>>> 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]])

Tags: importnumpyas编程np数组array例子
2条回答

简而言之,变量赋值创建对现有对象的新引用。

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

实际上这根本不是问题;这是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,
...

所以你看,ab实际上是指内存中的同一个位置,即同一个对象。对其中一个所做的任何更改都将反映在另一个中,因为它们只是同一事物的两个名称。

如果要实际复制数组,则必须调用方法显式地执行此操作。Numpy数组有一个copy方法,您可以将其用于此目的。所以如果你写信

b = a.copy()

然后Python将首先实际地复制数组—也就是说,它将留出一个新的内存区域,比如在地址0x123904381处,然后转到内存地址0x123674283,并将数组的所有值从内存的后一部分复制到前一部分。所以你有相同的内容放在记忆中的两个不同的地方。

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

现在,当您更改b的某个元素时,该更改不会出现在a中,因为ab不再引用计算机内存的同一部分。由于阵列数据有两个独立的副本,因此可以在不影响另一个副本的情况下更改其中一个副本。

相关问题 更多 >