视图和赋值之间的区别

Posted

技术标签:

【中文标题】视图和赋值之间的区别【英文标题】:Difference between a view and assignment 【发布时间】:2016-06-17 22:04:07 【问题描述】:

我可以理解分配、浅拷贝和深拷贝之间的区别。但我仍然不清楚视图(c=a)和分配(c=a.view())之间有什么区别。两者都反映了变化并且看起来相同。如果可能,请提供示例

我指的是这里的观点:https://docs.scipy.org/doc/numpy-1.11.0/reference/generated/numpy.ndarray.view.html。我不确定这些视图的行为是否类似于 dict 视图(https://docs.python.org/release/3.0.1/library/stdtypes.html#dictionary-view-objects)。

【问题讨论】:

您能给出这些术语的上下文吗?视图通常是一个数据库,而不是 Python 术语。但是python中有view objects 这些术语需要更多上下文。但是,很难想象它们可以在任何情况下进行比较。视图是一个东西,而赋值是一个动作。 @AbhishekBhatia "... in scipy" 将是您的问题中包含的非常相关的内容。 @TadhgMcDonald-Jensen:不过,第二个例子根本不是 NumPy 或 SciPy。第二个例子是关于 dict 视图。 @AbhishekBhatia:嗯,你已经设法让事情变得更加混乱。 c=a 是一个赋值,而c=a.view() 创建一个视图并将其分配给一个变量。它们几乎与您所说的相反。 【参考方案1】:

NumPy 中的数组对象是一个带有 data 指针的 ndarray 结构,该指针指向数组中的原始值。

b = a: 给数组起个名字就行了。 c = a.view():创建数组视图 a 意味着创建一个指向相同原始值的新 ndarray 结构。

这里是示例代码:

import numpy as np

a = np.array([1,2,3])
b = a
c = a.view()

print(id(a), id(b), id(c))
print(a.ctypes.data, b.ctypes.data, c.ctypes.data)

输出:

140328594430752 140328594430752 140328594428432
40268384 40268384 40268384
ab 具有相同的 id 表示它们是同一个对象。 都具有相同的data 指针意味着它们共享相同的原始数据。

这是在内存中创建的:

这里是关于 ndarray struct 的文档:

http://docs.scipy.org/doc/numpy-1.10.0/reference/c-api.types-and-structures.html#c.PyArrayObject

【讨论】:

另一种获取数据缓冲区信息的便捷方法是a.__array_interface__(包含data 指针的字典)。 b=a[:] 和类似的切片也会创建一个视图。 您好,感谢您的回答。我知道对象是什么。你能提供关于什么是数据指针的信息吗? 我添加了一个指向numpy文档的链接,数据指针是PyArrayObject中的数据字段。 你写了all have the same data pointer 但没有其他的。 @AbhishekBhatia 相同的数据指针意味着指针指向相同的地址。【参考方案2】:

字典 dictviewnumpy 数组视图无关。这只是dict.keys()dict.values()dict.items() 在 Python3 中创建的对象的一个​​覆盖术语。它们更像是生成器,需要 list(...) 包装器。在使用数组时试图理解这些只会让你感到困惑。

使用numpy 数组,您需要了解副本和视图之间的区别。这反过来又需要对数组对象是什么以及它如何存储数据有一个基本的了解。

https://docs.scipy.org/doc/numpy-dev/user/quickstart.html#copies-and-views

b = a

ba 的另一个名称。两个名字都指向同一个数组对象

b = a[:]
b = a.view()
b = a[:4]
b = a.reshape(1,-1)
b = np.array(a,copy=False)  # but read the np.array docs

b 是一个新的数组对象,但它与a 共享底层数据缓冲区。 b 中值的更改将在 a 中看到。 b 可能有不同的形状。

b = a.copy()
b = a.astype(int)
b = np.array(a, copy=True)
b = a[[1,2,3]]

b 是一个新数组,具有a 数据缓冲区的副本。 b 的更改独立于 a 的更改。

【讨论】:

以上是关于视图和赋值之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

赋值运算符和复制构造函数有啥区别?

+=和=+ C赋值运算符有啥区别[重复]

PHP关联数组赋值方法的区别

Python---copy()deepcopy()与赋值的区别

阻塞赋值和非阻塞赋值有何区别

CString 赋值的区别