视图和 numpy 数组的浅拷贝有什么区别? [英] What's the difference between a view and a shallow copy of a numpy array?

查看:24
本文介绍了视图和 numpy 数组的浅拷贝有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 NumPy 中,我知道对数组进行切片会给你一个视图",在我看来这与浅拷贝完全相同.它们有何不同?

In NumPy, I understand that slicing an array gives you a "view", which seems to me the exact same as a shallow copy. How are they different?

推荐答案

与包含对第一级元素对象的引用的 Python 列表对象(反过来可能引用更深层次的对象)不同,NumPy 数组仅引用存储数组所有维度的所有元素值的单个数据缓冲区,并且在此数据缓冲区之外没有元素对象的层次结构.

Unlike a Python list object which contains references to the first level of element objects (which in turn may reference deeper levels of objects), a NumPy array references only a single data buffer which stores all the element values for all the dimensions of the array, and there is no hierarchy of element objects beyond this data buffer.

列表的浅表副本将包含第一级元素引用的副本,并与原始列表共享引用的元素对象.NumPy 数组的浅拷贝应该包含什么不太明显.它应该 (A) 与原始共享数据缓冲区,还是 (B) 拥有自己的副本(这实际上使其成为深层副本)?

A shallow copy of a list would contain copies of the first level of element references, and share the referenced element objects with the original list. It is less obvious what a shallow copy of a NumPy array should contain. Should it (A) share the data buffer with the original, or (B) have its own copy (which effectively makes it a deep copy)?

NumPy 数组的视图是 A 意义上的浅拷贝,即它引用与原始数据相同的数据缓冲区,因此对原始数据的更改会影响视图数据,反之亦然.

A view of a NumPy array is a shallow copy in sense A, i.e. it references the same data buffer as the original, so changes to the original data affect the view data and vice versa.

库函数 copy.copy() 应该创建其参数的浅表副本,但当应用于 NumPy 数组时,它会创建意义上 B 的浅表副本,即新数组得到它自己的数据缓冲区副本,因此对一个数组的更改不会影响另一个.

The library function copy.copy() is supposed to create a shallow copy of its argument, but when applied to a NumPy array it creates a shallow copy in sense B, i.e. the new array gets its own copy of the data buffer, so changes to one array do not affect the other.

这里有一些代码显示了复制/查看 NumPy 数组的不同方法:

Here's some code showing different ways to copy/view NumPy arrays:

import numpy as np
import copy

x = np.array([10, 11, 12, 13])

# Create views of x (shallow copies sharing data) in 2 different ways
x_view1 = x.view()
x_view2 = x[:]          # Creates a view using a slice

# Create full copies of x (not sharing data) in 2 different ways
x_copy1 = x.copy()
x_copy2 = copy.copy(x)  # Calls x.__copy__() which creates a full copy of x

# Change some array elements to see what happens
x[0]       = 555        # Affects x, x_view1, and x_view2
x_view1[1] = 666        # Affects x, x_view1, and x_view2
x_view2[2] = 777        # Affects x, x_view1, and x_view2
x_copy1[0] = 888        # Affects only x_copy1
x_copy2[0] = 999        # Affects only x_copy2

print(x)                # [555 666 777  13]
print(x_view1)          # [555 666 777  13]
print(x_view2)          # [555 666 777  13]
print(x_copy1)          # [888  11  12  13]
print(x_copy2)          # [999  11  12  13]

上面的示例创建了整个原始数组索引范围的视图,并具有与原始相同的数组属性,这不是很有趣(可以用简单的别名替换,例如 x_alias = x).视图的强大之处在于它们可以是原件的选定部分的视图,并且具有不同的属性.这在接下来的几行代码中得到了证明,这些代码扩展了上面的例子:

The above example creates views of the entire original array index range and with the same array attributes as the original, which is not very interesting (could be replaced with a simple alias, e.g. x_alias = x). What makes views powerful is that they can be views of chosen parts of the original, and have different attributes. This is demonstrated in the next few lines of code which extend the above example:

x_view3 = x[::2].reshape(2,1) # Creates a reshaped view of every 2nd element of x
print(x_view3)          # [[555]
                        #  [777]]
x_view3[1] = 333        # Affects 2nd element of x_view3 and 3rd element of x
print(x)                # [555 666 333  13]
print(x_view3)          # [[555]
                        #  [333]]

这篇关于视图和 numpy 数组的浅拷贝有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆