【问题标题】:Whats the difference between `y = x` and `y = x[:]` with x a numpy-ndarray?`y = x` 和 `y = x[:]` 与 x 一个 numpy-ndarray 有什么区别?
【发布时间】:2021-06-07 14:43:22
【问题描述】:

我正在阅读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 显示这种特殊行为,其中取决于复制修改数据的方法有时会,有时不会'不要引发错误。

【问题讨论】:

  • @Ch3steR 我不认为x[:]x 的副本(它是基本切片,不应该),因为在第二个作业中修改y 仍然会修改x
  • @QuangHoang 你是对的。撤回了我的评论。
  • 不过,x[:]x视图,具有相同的数据但单独的元数据(包括.flag.writeable)。这就是为什么我们可以通过y写入x的内存。

标签: python numpy numpy-ndarray


【解决方案1】:

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 标志,那么该副本也将取消设置可写标志,并且您将获得一个只读的浅拷贝。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-16
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多