5

我了解基本的 Python 参考资料,例如 a+=b 和 a=a+b 之间的区别,但这让我感到困惑。

import numpy as np
arr1 = np.arange(6).reshape(2,3)
arr2 = arr1[0]
arr2 is arr1[0] #returns False, when I expect True
arr1[0] = [7,8,9]
arr2 #[7,8,9], when I expect [0,1,2] since the 'is' returned False

这里发生了什么?

4

5 回答 5

8

当您索引 numpy 数组时,您会创建一个新视图(它本身就是一个 numpy 数组)。这是一个不同的对象,因此is失败了,但它是对同一块“诚实实际硬件内存”的视图。因此,当您修改该视图时,您会修改可能存在另一个视图的那部分内存。

编辑:您实际上可以通过检查数组的ctypes.data属性来查看与 numpy 数组关联的内存的起始地址。

In [1]: import numpy as np

In [2]: arr1 = np.arange(6).reshape(2,3)

In [3]: arr2 = arr1[0]

In [4]: arr2.ctypes.data
Out[4]: 39390224

In [5]: arr1[0].ctypes.data
Out[5]: 39390224

相同!

于 2013-05-21T17:10:41.627 回答
4

如果需要检查两个numpy数组是否指向同一个数据,使用base属性。从你的例子:

>>> arr1 = np.arange(6).reshape(2,3)
>>> arr2 = arr1[0]
>>> arr1
array([[0, 1, 2],
       [3, 4, 5]])
>>> arr1.base # arr1 is a view of the array before reshaping!
array([0, 1, 2, 3, 4, 5])
>>> arr2.base
array([[0, 1, 2],
       [3, 4, 5]])
>>> arr2.base is arr1
True

从 numpy 1.7 开始,base一直深入到原始数组。从发行说明:

ndarrays 上的.base属性(用于视图以确保拥有内存的底层数组不会过早释放)现在在您拥有视图视图时折叠引用。例如::

a = np.arange(10)
b = a[1:]
c = b[1:]

在 numpy 1.6 中,c.baseisbc.base.baseis a。在 numpy 1.7 中, c.basea.

于 2013-05-21T18:08:26.977 回答
0

'is' 运算符比较两个对象的身份;id() 函数返回一个表示其身份的整数(当前实现为其地址)。

http://docs.python.org/2/reference/datamodel.html

例如,

a = 1, b = 1
a is b
Out[26]:True

id(a)
Out[27]:37470472L

id(b)
Out[27]:37470472L

id(1)
Out[27]:37470472L

三人的身份相同。但,

a = [1]
b = [1]
a is b
Out[26]:False

id(a)
Out[37]:142781064L

id(b)
Out[38]:142780616L

因此,同样的事情发生在数组中。他们没有相同的身份。

于 2013-05-21T21:39:03.490 回答
0
>>> arr1 = np.arange(6).reshape(2,3)
>>> arr1
array([[0, 1, 2],
       [3, 4, 5]])
>>> arr2 = arr1[0]
>>> arr2
array([0, 1, 2])

所以是的,arr1[0]并且arr2是平等的。然而,

>>> arr2 is arr1[0]
False

因为 is 不是比较 ndarrays 的工具。使用is,您可以检查arr1[0]arr2是否是同一个对象,而事实并非如此。试试看==,你会得到

>>> arr2 == arr1[0]
array([ True,  True,  True], dtype=bool)

或使用numpy.equal(t1,t2)

>>> np.equal(arr2, arr1[0])
array([ True,  True,  True], dtype=bool)

然后你想对你的平等测试有一个布尔答案,做

>>> (np.equal(arr2, arr1[0])).all()
True
于 2013-05-21T18:06:58.600 回答
0

您混淆了is,===运算符。

  • is进行身份检查。使用它来查看两个变量是否实际上指向同一个对象,而不仅仅是具有相同的值
  • =是赋值运算符。它为变量(或切片,如您的情况)分配一个值。
  • ==相等运算符。它检查两个对象是否具有相同的语义值。

所以在你的情况下:

arr2 == arr[0] # now should return True

当您从数组中读取值时,Numpy 似乎会创建新对象。因此,每次阅读时,都会创建一个新对象。所以两次读取生成不同的对象,所以is给出False结果。

于 2013-05-21T16:54:29.277 回答