`y = x` 和 `y = x[:]` 之间有什么区别,x 是一个 numpy-ndarray?

问题描述

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

y = x

(Python 3.7.2,numpy 1.16.2)

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

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

解决方法

y = x 只是添加了对现有对象的另一个引用,这里没有复制。这只是将同一对象的另一个名称添加到本地命名空间中,因此它的行为方式与 x 相同。

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

>>> x = np.array([1])
>>> y = x[:]
>>> x.flags.owndata,y.flags.owndata
(True,False)

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)

请注意,如果您在复制 writeable 之前关闭 x 标志,那么该副本也将具有未设置的可写标志,并且您将拥有只读浅拷贝。