`y = x` 和 `y = x[:]` 与 x 是一个 numpy-ndarray 有什么区别?
Whats the difference between `y = x` and `y = x[:]` with x a numpy-ndarray?
我正在阅读 this 问题,关于不可变的 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])
(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)
请注意,如果您在 复制 x
之前关闭 writeable
标志 ,那么副本也将取消设置可写标志,您将有一个只读的浅拷贝。
我正在阅读 this 问题,关于不可变的 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])
(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)
请注意,如果您在 复制 x
之前关闭 writeable
标志 ,那么副本也将取消设置可写标志,您将有一个只读的浅拷贝。