首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >array_2 = array_1与array_2 = array_1.view()

array_2 = array_1与array_2 = array_1.view()
EN

Stack Overflow用户
提问于 2021-11-24 06:56:35
回答 1查看 178关注 0票数 4

它们之间的区别是什么:

代码语言:javascript
复制
array_2 = array_1
array_2 = array_1.view()

例如,我想要一个示例,在第一种情况下将array_2更改为array的效果在第二种情况下会有所不同

EN

回答 1

Stack Overflow用户

发布于 2021-11-24 08:29:15

要理解的关键是,赋值永远不会复制或创建新的对象。赋值只是将相同的对象分配给一个新的名称。它为同一对象创建了一个“别名”--同一对象的不同名称。视图创建一个新对象,该对象共享相同的底层基元缓冲区,即存储numpy数据的连续基元数组。因此,对该数据的更改对使用该缓冲区的所有python对象都是可见的。

考虑一下:

代码语言:javascript
复制
>>> import numpy as np
>>> array = np.array([-3, -2, -1, 0, 1, 2, 3, 4], dtype=np.int64)
>>> array_view = array.view()
>>> array_alias = array
>>> array_alias is array
True
>>> array_view is array
False

因此arrayarray_alias是两个不同的名称,指的是同一个Python对象,也就是我们在开始时创建的numpy.ndarrayarrayarray_view是两个独立的Python对象。

如果我修改对象,那么显然引用同一对象的两个名称将能够看到更改:

代码语言:javascript
复制
>>> array.dtype = np.uint64
>>> array
array([18446744073709551613, 18446744073709551614, 18446744073709551615,
                          0,                    1,                    2,
                          3,                    4], dtype=uint64)
>>> array_alias
array([18446744073709551613, 18446744073709551614, 18446744073709551615,
                          0,                    1,                    2,
                          3,                    4], dtype=uint64)

但是视图不会

代码语言:javascript
复制
>>> array_view
array([-3, -2, -1,  0,  1,  2,  3,  4])

但是,如果我修改了数据,因为两个不同的对象(即原始数组和视图)都引用相同的底层缓冲区,所以更改对别名和视图是可见的:

代码语言:javascript
复制
>>> array
array([18446744073709551613, 18446744073709551614, 18446744073709551615,
                       1337,                    1,                    2,
                          3,                    4], dtype=uint64)
>>> array_alias
array([18446744073709551613, 18446744073709551614, 18446744073709551615,
                       1337,                    1,                    2,
                          3,                    4], dtype=uint64)
>>> array_view
array([  -3,   -2,   -1, 1337,    1,    2,    3,    4])

下面是另一个例子,使用切片,另一个为numpy对象创建视图的操作:

代码语言:javascript
复制
>>> array = np.arange(16)
>>> array
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])
>>> array_slice = array[::4]
>>> array_slice
array([ 0,  4,  8, 12])
>>> array is array_slice
False

我可以独立操作这些对象:

代码语言:javascript
复制
>>> array_slice.shape = (2, 2)
>>> array_slice
array([[ 0,  4],
       [ 8, 12]])
>>> array
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])

但我不能独立操作他们的数据:

代码语言:javascript
复制
>>> array_slice[:] = 1337
>>> array_slice
array([[1337, 1337],
       [1337, 1337]])
>>> array
array([1337,    1,    2,    3, 1337,    5,    6,    7, 1337,    9,   10,
         11, 1337,   13,   14,   15])

最后,请注意,当您想要创建一个新对象时,通常会调用np.ndarray.view方法,该对象是原始数组的视图,但具有不同的数据类型,因此:

代码语言:javascript
复制
>>> array = np.array([-2, -1, 0, 1, 2], dtype=np.int64)
>>> bytewise = array.view(np.uint8)
>>> bytewise
array([254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
       255, 255, 255,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
         0,   0,   0,   0,   0,   0,   2,   0,   0,   0,   0,   0,   0,
         0], dtype=uint8)

让我们适当地修改视图的形状,看看64位有符号整数是如何以原始字节表示的(即8位整数!):

代码语言:javascript
复制
>>> bytewise.shape = array.shape[0], 8
>>> bytewise
array([[254, 255, 255, 255, 255, 255, 255, 255],
       [255, 255, 255, 255, 255, 255, 255, 255],
       [  0,   0,   0,   0,   0,   0,   0,   0],
       [  1,   0,   0,   0,   0,   0,   0,   0],
       [  2,   0,   0,   0,   0,   0,   0,   0]], dtype=uint8)
>>> array
array([-2, -1,  0,  1,  2])
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70091813

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档