`y = x` 和 `y = x[:]` 与 xa numpy-ndarray 有什么区别?

Mar*_*ica 6 python numpy numpy-ndarray

我正在阅读关于不可变 numpy 数组的这个问题,并且在对其中一个答案的评论中,有人表明给定的技巧在y = x[:]使用而不是y = x.

>>> import numpy as np
>>> x = np.array([1])
>>> y = x
>>> x.flags.writeable = False
>>> y[0] = 5
Traceback (most recent call last):
  File "<pyshell#42>", line 1, in <module>
    y[0] = 5
ValueError: assignment destination is read-only
>>> del x, y
>>> x = np.array([1])
>>> y = x[:]
>>> x.flags.writeable = False
>>> y[0] = 5
>>> x
array([5])
Run Code Online (Sandbox Code Playgroud)

(Python 3.7.2,numpy 1.16.2)

这两者之间甚至有什么区别,为什么在这种特定情况下它们的行为如此不同?

编辑:不能回答我的问题,因为它只询问使用列表的情况,我想知道为什么 numpy ndarray 显示这种特殊的行为,其中取决于复制修改数据的方法有时会,有时不会引发错误.

wim*_*wim 4

y = x只是添加对现有对象的另一个引用,此处不进行复制。这只是将同一对象的另一个名称添加到本地名称空间中,因此它的行为在各方面都与x.

y = x[:]创建 numpy 数组的浅表副本。这是一个新的Python对象,但内存中的底层数组数据将是相同的。然而,这些标志现在是独立的:

>>> x = np.array([1])
>>> y = x[:]
>>> x.flags.owndata, y.flags.owndata
(True, False)
Run Code Online (Sandbox Code Playgroud)

owndata标志显示这y只是 的数据视图x。将可写标志设置为打开x不会更改 的y标志,因此y仍然保留 的数据的可写视图x

>>> x.flags.writeable, y.flags.writeable
(True, True)
>>> x.flags.writeable = False
>>> x.flags.writeable, y.flags.writeable
(False, True)
Run Code Online (Sandbox Code Playgroud)

请注意,如果您在复制之前关闭该writeable标志,则副本也将取消设置可写标志,并且您将拥有只读浅副本。x